【noip2015】d2解题报告
t1:跳石头
裸的二分
#include<iostream> #include<cstdio> using namespace std; int n,ans,l,r,len,m,a[50050]; int main() { scanf("%d%d%d",&len,&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); l=0,r=len; while(l+1<r) { int mid=l+r>>1,ci=0,tail=0; for(int i=1;i<=n;i++) { if(a[i]-a[tail]<mid) ci++; else tail=i; } if(ci>m) r=mid; else l=mid; } if(n==0) l=len; printf("%d",l); }
t2:子串,一个灰常有难度的序列dp……和字符串的操作基本没关系
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<queue> using namespace std; int t,n,shu[20],ans,x,y; void dfs(int x) { int c1=0,c2=0,c3=0,c4=0; for(int i=1;i<=14;i++) { if(shu[i]==1) c1++; else if(shu[i]==2) c2++; } for(int i=1;i<=14;i++) { if(shu[i]!=3) continue; c3++; if(c1>=1) c1--; else if(c2>=1) c2--; } for(int i=1;i<=14;i++) { if(shu[i]!=4) continue; c4++; if(c1>=2) c1-=2; else if(c2>=2) c2-=2; else if(c2>=1) c2--; } ans=min(ans,x+c1+c2+c3+c4); for(int i=1;i<=8;i++) { int j; for(j=i;j<=12;j++) { if(shu[j]<1) break; shu[j]--; if(j-i>=4) dfs(x+1); } for(int k=i;k<=j-1;k++) shu[k]++; } for(int i=1;i<=10;i++) { int j; for(j=i;j<=12;j++) { if(shu[j]<2) break; shu[j]-=2; if(j-i>=2) dfs(x+1); } for(int k=i;k<=j-1;k++) shu[k]+=2; } for(int i=1;i<=11;i++) { int j; for(j=i;j<=12;j++) { if(shu[j]<3) break; shu[j]-=3; if(j-i>=1) dfs(x+1); } for(int k=i;k<=j-1;k++) shu[k]+=3; } return; } int main() { //2freopen("qwq.out","w",stdout); scanf("%d%d",&t,&n); while(t--) { ans=n; memset(shu,0,sizeof(shu)); for(int i=1;i<=n;i++) { scanf("%d%d",&x,&y); if(x==0) shu[14]++; else if(x==1) shu[12]++; else if(x==2) shu[13]++; else shu[x-2]++; } dfs(0); cout<<ans<<'\n'; } fclose(stdin); fclose(stdout); return 0; }
t3:没写成,丢dalao链接:http://blog.csdn.net/qq_36312502/article/details/78126264