吉大第二届青云杯复赛第6题
作者:互联网
题目链接
题意分析
我就是死在了这道题上
首先我们可以明白的是 所有\(a_i\)增加的上限就是\(lim=Min_{1≤i≤n}b_i\)
然后我们令\(c_i=lim-b_i\)
如果存在\(c_i<0\)的话 那是绝对不符合要求的
这样的话我们的操作就变成了
1.选择一个\(k(1≤k≤n)\)使得所有\(c_1,c_2,...,c_k\)全部\(-1\)
2.选择一个\(k(1≤k≤n)\)使得所有\(c_k,c_{k+1},...,c_n\)全部\(-1\)
然后的话 我们就是躲过这两种操作使得所有\(c_i\)相等并且都是\(≥0\)
当时想到了这里 然后就走歪了 但是当时也明白 这道题的正解应该是比较简单的
但是真正看到正解的那一刻 我还是震惊到了
整体加减 我们想到了什么 差分!!!
我们让\(c_0=0\) 然后的话\(d_i=c_i-c_{i-1}(1≤i≤n)\)
然后我们再回头看这两种操作
1.选择一个\(k(1≤k≤n)\)使得\(d_1-1,d_{k+1}+1\)
2.选择一个\(k(1≤k≤n)\)使得\(d_k-1\)
然后的话 我们就是看看
\[d_1 + \sum_{i=2}^n{[d_i<0]d_i}≥0 \]这样的话就可以了
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define N 1000080
using namespace std;
int T,n,lim,tot;
bool flag;
int cdy[N],wzy[N],num[N],d[N];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);lim=2100000000;flag=0;tot=0;
for(int i=1;i<=n;++i) scanf("%d",&cdy[i]);
for(int i=1;i<=n;++i) scanf("%d",&wzy[i]);
for(int i=1;i<=n;++i) lim=min(lim,wzy[i]);
for(int i=1;i<=n;++i) num[i]=lim-cdy[i];
for(int i=1;i<=n;++i) if(num[i]<0) {flag=1;break;}
if(flag) {puts("No");continue;}
for(int i=1;i<=n;++i) d[i]=num[i]-num[i-1];
for(int i=1;i<=n;++i)
if(i==1) tot+=d[i];
else if(d[i]<0) tot+=d[i];
if(tot>=0) puts("Yes");
else puts("No");
}
return 0;
}
标签:青云,int,lim,然后,使得,吉大,include,我们,复赛 来源: https://www.cnblogs.com/LovToLZX/p/14058900.html