CF1329A Dreamoon Likes Coloring(贪心)
对于某一类构造题,我们先要找出不符合条件的情况输出-1
之后剩下的都是肯定有答案的
然后我们就开始做这道题目,首先一个想法我们肯定想保证如何不被覆盖
这样我们肯定是想每个点的涂的位置只向后移一位,这样至少一个位置不会被覆盖
但这样我们会发现有可能涂不满,因此我们再用新思路和他结合一下,我们会想到一个边界
如果在边界点上涂,后面就肯定有方案可以涂满,那么这么边界点就是后缀和,这也是最优的,因为跳到了边界。
因此我们从后往前看,当剩下要涂的空格大于i的时候,我们就涂后缀的位置,不然就涂i,因为要保证不被别的颜色覆盖,所以i也是一个边界点。
i这个边界点表示,如果我的后缀和已经小于我当前的位置,那么剩下的我就一位一位涂就好了。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #include<string> #include<vector> using namespace std; typedef long long ll; const int N=2e5+5; int a[N]; ll s[N]; ll ans[N]; int main(){ int n; int m; cin>>n>>m; int i; int flag=0; for(i=1;i<=m;i++){ cin>>a[i]; if(n-a[i]<i-1) flag=1; } for(i=m;i>=1;i--){ s[i]=s[i+1]+a[i]; } if(s[1]<n) flag=1; if(flag){ cout<<-1<<endl; return 0; } for(i=1;i<=m;i++){ ans[i]=max((ll)i,n-s[i]+1); } for(i=1;i<=m;i++) cout<<ans[i]<<" "; cout<<endl; return 0; }
没有人不辛苦,只有人不喊疼