A
签到
B
直接DP,f[i][j]表示前i步j步向左的最大值,位置可以直接计算
#include<bits/stdc++.h> using namespace std; const int N=1e5+7; int n,k,z,ans,a[N],f[N][6]; int main() { int T;scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&k,&z); for(int i=1;i<=n;i++)for(int j=0;j<=z;j++)f[i][j]=0; for(int i=1;i<=n;i++)scanf("%d",&a[i]); f[0][0]=a[1]; for(int i=1;i<=k;i++) for(int j=0;j<=min(i-1,z);j++) { int pos=i-2*j; if(pos>1&&j<z)f[i][j+1]=max(f[i][j+1],f[i-1][j]+a[pos-1]); if(pos<n)f[i][j]=max(f[i][j],f[i-1][j]+a[pos+1]); } ans=0; for(int i=0;i<=z;i++)ans=max(ans,f[k][i]); printf("%d\n",ans); } }
C
求最少删除次数等价于求最长序列。容易发现,最长序列有两种情况:1、全为字符a;2、长度为偶数,ababab交替。方案1记录数量最多的数字,方案2枚举ab扫描一遍即可,复杂度O(81Σn)
#include<bits/stdc++.h> using namespace std; int n,ans; char s[200050]; int main() { int T;scanf("%d",&T); while(T--) { scanf("%s",s+1); n=strlen(s+1); int num; ans=0; for(int i='0';i<='9';i++) { num=0; for(int j=1;j<=n;j++)if(s[j]==i)num++; ans=max(ans,num); } for(int a='0';a<='9';a++) for(int b='0';b<='9';b++) if(a!=b) { int now=a,num=0; for(int i=1;i<=n;i++)if(s[i]==now) { num++; now=now==a?b:a; } if(num%2)num--; ans=max(ans,num); } printf("%d\n",n-ans); } }
D
对于两条线段,不妨三种情况:1、完全包含;2、部分包含;3、无交集。前两种直接计算,尽量改变重叠部分。第三种可以枚举改变i组线段,然后转化为第二种方案。时间复杂度O(Tn)(不然T,n给你那么小干嘛?)
#include<bits/stdc++.h> using namespace std; typedef long long ll; int T; ll n,k,l1,r1,l2,r2,ans; int main() { cin>>T; while(T--) { cin>>n>>k>>l1>>r1>>l2>>r2; if(l1>l2||l1==l2&&r1<r2)swap(l1,l2),swap(r1,r2); if(r1>=r2) { ll rst=(r1-l1)-(r2-l2); if(k<=(r2-l2)*n)puts("0"); else if(k<=(r1-l1)*n)printf("%lld\n",k-(r2-l2)*n); else printf("%lld\n",rst*n+(k-(r1-l1)*n)*2); } else if(r1>=l2) { ll rst=(r2-l1)-(r1-l2); if(k<=(r1-l2)*n)puts("0"); else if(k<=(r2-l1)*n)printf("%lld\n",k-(r1-l2)*n); else printf("%lld\n",rst*n+(k-(r2-l1)*n)*2); } else{ ans=9e18; for(int i=1;i<=n;i++) { ll sum=i*(l2-r1); if(k<=(r2-l1)*i)sum+=k; else sum+=(r2-l1)*i+(k-(r2-l1)*i)*2; ans=min(ans,sum); } printf("%lld\n",ans); } } }
E
老年选手不会用脑子了!若a月b日和b月a日如果是一周的同一天,则(b-1)*d+a-( (a-1)*d+b)被w整除,化简得(b-a)(d-1)%w==0,设c=b-a,则c*(d-1)%w==0。若(d-1)%w=0,则c为任意正整数 ,ans=md*(md-1)/2,md=min(m,d)。若(d-1)%w!=0,那c是lcm(w,(d-1)%w)/(d-1)%w的整数倍
#include<bits/stdc++.h> using namespace std; int main() { int T;scanf("%d",&T); while(T--) { int m,d,w,g;scanf("%d%d%d",&m,&d,&w); g=__gcd(w,d-1),w/=g,m=min(m,d); long long y=m/w; printf("%lld\n",y*m-y*(y+1)/2*w); } }
rank=216 rating+=222
新号卡线上紫啦!