2016-09-27-DP小练
Posted Konjak谷弱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016-09-27-DP小练相关的知识,希望对你有一定的参考价值。
得分250。。我真是个250。。。
犯了一些很搞笑的错。。
f[i][j][k]表示第i个苹果,现在在j这个位置,还能用k次转移。
用i去更新i+1。
时间复杂度1000*2*30;
转移方程有个地方减一写错位了。。这么明显的错竟然没有看见。。50分TAT
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 7 const int N=1100,M=50; 8 int n,K,f[N][3][M],t[N]; 9 10 int maxx(int x,int y){return x>y ? x:y;} 11 void g(int &x,int y){x=maxx(x,y);} 12 13 int main() 14 { 15 // freopen("a.in","r",stdin); 16 freopen("bcatch.in","r",stdin); 17 freopen("bcatch.out","w",stdout); 18 scanf("%d%d",&n,&K); 19 for(int i=1;i<=n;i++) scanf("%d",&t[i]),t[i]--; 20 memset(f,-63,sizeof(f)); 21 f[0][0][K]=0; 22 for(int i=0;i<n;i++) 23 { 24 int now=t[i+1]; 25 for(int k=0;k<=K;k++) 26 { 27 g(f[i+1][now][k],f[i][now][k]+1); 28 if(k>=1) g(f[i+1][now][k-1],f[i][1-now][k]+1); 29 g(f[i+1][1-now][k],f[i][1-now][k]); 30 if(k>=1) g(f[i+1][1-now][k-1],f[i][1-now][k]); 31 } 32 } 33 int ans=0; 34 for(int k=0;k<=K;k++) ans=maxx(ans,maxx(f[n][0][k],f[n][1][k])); 35 printf("%d\\n",ans); 36 return 0; 37 }
f[i][j]表示当前时间为i,能力值为j时的最大滑雪次数。
预处理:给课程先排一次序;p[i]表示能力值为i时滑一次雪最少要多久。
然后就是要不去上课;要不去滑雪。
时间复杂度10^4*100。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int N=100010; 9 struct node{ 10 int c,d; 11 }a[N]; 12 struct nod{ 13 int m,l,A; 14 }b[N]; 15 int n,s,t,p[N],f[11000][110],mx[N]; 16 17 // bool cmp1(node x,node y) 18 // { 19 // if(x.c==y.c) return x.d<y.d; 20 // return x.c<y.c; 21 // } 22 23 bool cmp2(nod x,nod y){return x.m<y.m;} 24 int maxx(int x,int y){return x>y ? x:y;} 25 int minn(int x,int y){return x<y ? x:y;} 26 void g(int &x,int y){x=maxx(x,y);} 27 28 int main() 29 { 30 // freopen("a.in","r",stdin); 31 freopen("ski.in","r",stdin); 32 freopen("ski.out","w",stdout); 33 scanf("%d%d%d",&t,&s,&n); 34 memset(p,63,sizeof(p)); 35 for(int i=1;i<=s;i++) 36 { 37 scanf("%d%d%d",&b[i].m,&b[i].l,&b[i].A); 38 } 39 for(int i=1;i<=n;i++) 40 { 41 scanf("%d%d",&a[i].c,&a[i].d); 42 p[a[i].c]=minn(p[a[i].c],a[i].d); 43 } 44 for(int i=1;i<=100;i++) p[i]=minn(p[i],p[i-1]); 45 // sort(a+1,a+1+n,cmp1); 46 sort(b+1,b+1+s,cmp2); 47 b[s+1].m=0; 48 int ind=1,ans=0; 49 memset(f,-63,sizeof(f)); 50 memset(mx,-63,sizeof(mx)); 51 f[0][1]=0; 52 for(int i=0;i<=t;i++) 53 for(int j=1;j<=100;j++) 54 { 55 g(f[i][j],mx[j]); 56 while(b[ind].m<i && ind<=s) ind++; 57 if(b[ind].m==i) g(f[i+b[ind].l][b[ind].A],f[i][j]); 58 g(f[i+p[j]][j],f[i][j]+1); 59 g(mx[j],f[i][j]); 60 if(i==t) ans=maxx(ans,f[i][j]); 61 } 62 printf("%d\\n",ans); 63 return 0; 64 }
这题是我被卡住的一题。。因为我一直在想它为了达到后面的限制,前面可能要特意往下走一点。。
一出来发现自己好搞笑。。
首先我们从后往前预处理一遍,s[i]=minn(s[i],s[i+1]+dis(i~i+1)),这样就保证了满足当前的限制,以后的限制就一定有办法达到!
然后就是一个贪心了。
对于当前的v,下一个限制s[i+1],它们之间的速度差k=s[i+1]-v,距离d=dis(i~i+1)
设加速x秒,减速y秒。
x+y=d
x - y=k
所以最高速度x=(d+k)/2;
ans取max。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int N=110000; 9 int l,n,pl,t[N],s[N]; 10 struct node{ 11 int t,s; 12 }a[N]; 13 14 bool cmp(node x,node y){return x.t<y.t;} 15 int maxx(int x,int y){return x>y ? x:y;} 16 int minn(int x,int y){return x<y ? x:y;} 17 18 int main() 19 { 20 // freopen("a.in","r",stdin); 21 freopen("bobsled.in","r",stdin); 22 freopen("bobsled.out","w",stdout); 23 scanf("%d%d",&l,&n); 24 pl=0;t[0]=0; 25 for(int i=1;i<=n;i++) scanf("%d%d",&a[i].t,&a[i].s); 26 sort(a+1,a+1+n,cmp); 27 for(int i=n;i>=1;i--) 28 { 29 int d=a[i].t-a[i-1].t; 30 a[i-1].s=minn(a[i-1].s,a[i].s+d); 31 } 32 int v=1,ans=0; 33 for(int i=1;i<=n;i++) 34 { 35 int d=a[i].t-a[i-1].t; 36 if(v+d<=a[i].s) v=v+d,ans=maxx(ans,v); 37 else 38 { 39 int k=a[i].s-v; 40 ans=maxx(ans,v+(d+k)/2); 41 v=a[i].s; 42 } 43 // printf("v = %d\\n",v); 44 } 45 ans=maxx(ans,v+l-a[n].t); 46 printf("%d\\n",ans); 47 return 0; 48 }
f[i][j]表示当前扫到第i只奶牛,余数是j。
转移方程就直接看把。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int N=2100,M=1100,Mod=(int)1e8; 9 int n,m,f[N][M],a[N]; 10 11 int maxx(int x,int y){return x>y ? x:y;} 12 void g(int &x,int y){x=(x+y)%Mod;} 13 14 int main() 15 { 16 // freopen("a.in","r",stdin); 17 freopen("fristeam.in","r",stdin); 18 freopen("fristeam.out","w",stdout); 19 scanf("%d%d",&n,&m); 20 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 21 memset(f,0,sizeof(f)); 22 f[0][0]=1; 23 for(int i=0;i<=n;i++) 24 { 25 for(int j=0;j<=m;j++) 26 { 27 g(f[i+1][(j+a[i+1])%m],f[i][j]); 28 g(f[i+1][j],f[i][j]); 29 // printf("f [ %d ] [ %d ] = %d\\n",i,j,f[i][j]); 30 } 31 } 32 printf("%d\\n",f[n][0]-1); 33 return 0; 34 }
以上是关于2016-09-27-DP小练的主要内容,如果未能解决你的问题,请参考以下文章
Java反射小练之手写BeanUtils的copyProperties(Upgrade)