https://codeforces.com/problemset/problem/1256/C
思路:
直接每次跳最大步数可能板子放不下。
所以开始把所有板子放在最右边叠起来,然后每次跳最大的,把当前板子左端点拉过来,下一次从这个板子的右端点开跳。更新右边板子的放置情况。
细节:
注意更新情况的时候可能右边的板子已经被左边过来的放置覆盖了一部分,所以更新放置的循环要从max(原先开始的地方,被覆盖的终端+1)
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e3+100;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL n,m,d;
LL c[maxn];
LL ans[maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
cin>>n>>m>>d;
LL res=0;
for(LL i=1;i<=m;i++) cin>>c[i],res+=c[i];
if(res+(m+1)*(d-1)<n){
cout<<"NO"<<"\n";
}
else{
cout<<"YES"<<"\n";
LL j=1;LL temp=c[j];
for(LL i=n+1-res;i<=n;i++){
if(temp>0){
ans[i]=j;temp--;
}
else if(temp==0) {
j++;temp=c[j];ans[i]=j;temp--;
}
}
LL k=1;
LL last=n+1-res;
for(LL i=0;i<=n;i++){
LL l=i+1;LL r=i+d;
if(r>n) break;
if(ans[r]==0){
for(LL p=r;p<=c[k]+r-1;p++){
ans[p]=k;
}
for(LL p=max(last,c[k]+r-1+1);p<=c[k]+last-1;p++){
ans[p]=0;
}
LL nlast=c[k]+last;
last=nlast;
i=(r+c[k]-1-1);
k++;
}
}
for(LL i=1;i<=n;i++){
cout<<ans[i]<<" ";
}
cout<<"\n";
}
return 0;
}