HDU 6205 card card card(特殊尺取)

    技术2022-07-10  154

     有一个长度为 n 的序列(ai),每个数对应着一个罚值 bi,之后开始从 a 序列的第一个数字开始取数,只要拿的 a 序列数字之和不小于对应的 b 序列数字之和,则所拿数字合法。

    求在保证可以拿到的数字之和最大的情况下,初始最少要拿几个数放到序列后面去

     

    我们将 b 与处理一下,将罚值与奖值加起来,这样只要判断是否贡献大于0即可

    只要当前区间 a 序列之和不小于 b 序列之和,e 就继续往后扩展,扩展后如果所拿数字之和大于已有最大值则更新答案,然后把 s 移动到 e+1 继续上述过程

    const int N=2e6+5; int n,m,t; int i,j,k; int a[N],b[N]; int main() { IOS; while(cin>>n){ for(i=1;i<=n;i++){ cin>>a[i]; a[n+i]=a[i]; } for(i=1;i<=n;i++){ cin>>b[i]; b[i]=a[i]-b[i]; b[i+n]=b[i]; } int s=1,e=1,ans=0,penalty=0,sum=0,maxx=0; while(s<=n){ //penalty=0,e=s,sum=0; while(e<=n*2 && penalty+b[e]>=0){ penalty+=b[e]; sum+=a[e]; e++; } if(sum>maxx){ maxx=sum; ans=s-1; } //s=e+1; penalty-=b[s]; sum-=b[s]; s++; } cout<<ans<<endl; } //PAUSE; return 0; }

    第一次用注释部分跑的,但是不大清楚网上大牛们为什么要将 s 移动到 e+1 继续跑,感觉不大严谨,后来自己写的竟然更快。。

    可能数据很水

     

    Processed: 0.018, SQL: 10