摘要: if(a>dp[i-j])dp[i]=min(dp[i],2*t+a); else dp[i]=min(dp[i],2*t+dp[i-j]);dp[i]表示第i个车到达对岸花的最少时间由于第 i 个车可以和它前面的 j(1~n-1)个车一起坐船,所以可以得到dp[i]=min(dp[i],dp[i-j]+2*t);但是第 i 个车到达的时间可能大于了dp[i-j],这样就会等第 i 个车,又得dp[i]=min(dp[i],i 到达时间+2*t);最后一次不用返回了,所以dp[m]-t;船运的次数:num[i]=num[i-j]+1;View Code #include <stdi 阅读全文
posted @ 2011-11-12 19:38 104_gogo 阅读(213) 评论(0) 推荐(0) 编辑
摘要: 抱着试试的态度,居然1A了..方法就是,正向和反向各求一次连续子段和,并且把每达到的位置的最大和保存起来ans=max(ans,sum1[i]+sum2[i+1]);sum1[i]表示第i个数前面的最大连续子段的和,sum2[i+1]表示从i+1个数后面的最大连续子段和View Code #include <stdio.h>int ar[100005],sum1[100000],sum2[100000];int main(){ int n,i,j,sum,max,ans; while (scanf("%d",&n)&&n) { max=a 阅读全文
posted @ 2011-11-12 13:20 104_gogo 阅读(179) 评论(0) 推荐(0) 编辑
摘要: 听说这是个LIS的题,画了画图,发现是这样的..View Code #include <stdio.h>int ar[500005],vis[500000];int main(){ int n,i,j,k,m,p,r,l=1; while (scanf("%d",&n)!=EOF) { for (i=0;i<n;i++) { scanf("%d%d",&p,&r); ar[p]=r; } for (i=1,j=0,m=0;i<=n;i++) { ... 阅读全文
posted @ 2011-11-12 10:52 104_gogo 阅读(193) 评论(0) 推荐(0) 编辑
摘要: 0-1背包View Code #include <stdio.h>#include <string.h>int max(int a,int b){ return a>b?a:b;}int main(){ int T,i,j,n,V,a,val[1005],dp[1005]; scanf("%d",&T); while (T--) { scanf("%d%d",&n,&V); memset(dp,0,sizeof(dp)); for (i=0;i<n;i++)scanf("%d" 阅读全文
posted @ 2011-11-12 09:34 104_gogo 阅读(124) 评论(0) 推荐(0) 编辑
摘要: dp[i]+=dp[i-j];dp[i]表示传到第i个位置有多少种方法View Code #include <stdio.h>#include <string.h>int main(){ int n,m,i,j,dp[40]; while (scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0)break; memset(dp,0,sizeof(dp)); dp[1]=1; for (i=2;i<=n;i++) { for (j=0;j<=m;j++) ... 阅读全文
posted @ 2011-11-12 09:18 104_gogo 阅读(129) 评论(0) 推荐(0) 编辑