C:模拟:未跳到目的地之前先贪心放板子,能到达目的地后紧贴着放板子
先判能不能跳到目的地,能跳到再考虑是否需要将后面的板子往前移动

#include<bits/stdc++.h>
using namespace std;
#define N 20005
int sum,n,m,d,c[N],ans[N],ans1[N];
int main(){
cin>>n>>m>>d;
for(int i=1;i<=m;i++)cin>>c[i],sum+=c[i];
if(sum>n){puts("NO");return 0;}
int pos=0,id,R=0;
for(id=1;id<=m;id++){
if(pos+d>=n+1){//直接贴着放板子即可
for(int i=R+1;i<=R+c[id];i++)
ans[i]=id;
R+=c[id];
}
else {//贪心放板子
pos+=d;//跳到pos+d去
for(int i=pos;i<=pos+c[id]-1;i++)
ans[i]=id;
pos+=c[id]-1;
R=pos;
}
}
if(pos+d<n+1){puts("NO");return 0;}
if(pos+d>=n+1 && R<=n){
puts("YES");
for(int i=1;i<=n;i++)
cout<<ans[i]<<" ";
return 0;
}
int ind=n;
for(int i=R;i>=1;i--){
ind=min(ind,i);
if(ans[i]){
ans1[ind]=ans[i];
ind--;
}
}
puts("YES");
for(int i=1;i<=n;i++)
cout<<ans1[i]<<" ";
return 0;
}
D:贪心往前移动0即可,注意k是long long

#include<bits/stdc++.h>
using namespace std;
#define N 1000006
#define ll long long
long long n,k;
char s[N];
int main(){
int q;cin>>q;
while(q--){
scanf("%lld%lld",&n,&k);
scanf("%s",s+1);
ll tot=0,len=0;
for(int i=1;i<=n;i++){
if(s[i]=='1'){
tot++;
}
else {
if(tot<=k){
k-=tot;
++len;
swap(s[i],s[len]);
}
else {//只能往前移动k格
swap(s[i],s[i-k]);
break;
}
}
}
printf("%s\n",s+1);
}
}
E:贪心,肯定是分队伍越多越好,六个人的队显然没有两只三人队优
先排序,dp[i]表示取前i人的最优解,
枚举3<=j<=5,dp[i]=min(dp[i-j]+a[i]-a[i-j+1]);

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200005
struct Node{
ll id,a;
}p[N];
ll n,ans[N],dp[N],pre[N];
int cmp(Node a,Node b){
return a.a<b.a;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>p[i].a;
p[i].id=i;
}
sort(p+1,p+1+n,cmp);
dp[3]=p[3].a-p[1].a;
pre[3]=0;
dp[4]=p[4].a-p[1].a;
pre[4]=0;
dp[5]=p[5].a-p[1].a;
pre[5]=0;
for(int i=6;i<=n;i++){
dp[i]=dp[i-3]+p[i].a-p[i-2].a;
pre[i]=i-3;
for(int j=4;j<=5;j++){
if(i-j<3)continue;
if(dp[i]>dp[i-j]+p[i].a-p[i-j+1].a){
dp[i]=dp[i-j]+p[i].a-p[i-j+1].a;
pre[i]=i-j;
}
}
}
cout<<dp[n]<<' ';
int pos=n,now=0;
while(pos){
++now;
int tmp=pre[pos];
for(int i=tmp+1;i<=pos;i++)
ans[p[i].id]=now;
pos=tmp;
}
cout<<now<<'\n';
for(int i=1;i<=n;i++)cout<<ans[i]<<' ';
}
F:将一长段逆转转换成每次只逆转相邻两个字符,如果字符集不同,显然不行
字符集相同:分成两种情况:
1,某种字符出现>=2次,那么这种情况必然有解:先将这两个字符挨在一起,然后就可以随便搞了
2,每种字符出现1次,那么求出s转换成t的步数,偶数有解,奇数无解

#include<bits/stdc++.h>
using namespace std;
#define N 200005
char s[N],t[N];
int n,cnt1[100],cnt2[100],pos1[100],pos2[100];
int main(){
int T;cin>>T;
while(T--){
for(int i=0;i<26;i++)
cnt1[i]=cnt2[i]=pos1[i]=pos2[i]=0;
cin>>n;
cin>>s>>t;
for(int i=0;i<n;i++)
cnt1[s[i]-'a']++,cnt2[t[i]-'a']++;
int flag=0;
for(int i=0;i<26;i++)
if(cnt1[i]!=cnt2[i])
flag=1;
if(flag){puts("NO");continue;}
flag=0;
for(int i=0;i<26;i++)
if(cnt1[i]>=2)
flag=1;
if(flag){puts("YES");continue;}
int sum=0;
for(int i=0;i<n;i++){
int pos=i;
while(s[pos]!=t[i])pos++;
for(int j=pos;j>i;j--){
swap(s[j],s[j-1]);
sum++;
}
}
if(sum%2==0)cout<<"YES\n";
else puts("NO");
}
}
