标签:style blog color io os for sp div c
ZOJ 1234
这道题目我表示也还不是特别能理解。。。。还是太菜了T T
从后往前思考,因为只要后面有多的数在,那么C肯定是存在的,只要考虑是否把前两个数加在一起作为badness值这样两种情况来考虑
如果总数和3*j相同的话,那必然不用多考虑,它只能以前两个数的平方差作为badness值
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 int len[5005],dp[5005][1010]; 7 8 int main() 9 { 10 int T,k,n; 11 scanf("%d",&T); 12 while(T--){ 13 scanf("%d%d",&k,&n); 14 15 memset(dp,0x3f,sizeof(dp)); 16 for(int i=0;i<=n;i++) 17 dp[i][0]=0; 18 19 k+=8; 20 for(int i=1;i<=n;i++) 21 scanf("%d",len+i); 22 //i表示从i这点开始一直取到末尾,j表示取的筷子组 23 for(int i=n-2;i>=0;i--){ 24 for(int j=1;j<=k&&n-i+1>=3*j;j++){ 25 if(n-i+1 == 3*j) 26 dp[i][j] = dp[i+2][j-1] + (len[i]-len[i+1])*(len[i]-len[i+1]); 27 28 else if(n-i+1>3*j) 29 //这个语句表示对于最前面的那个数选不选取有两种可能性,不选,选了那么必然还要选取相邻的数和它作为一组 30 dp[i][j] = min(dp[i+1][j],dp[i+2][j-1] + (len[i]-len[i+1])*(len[i]-len[i+1])); 31 } 32 } 33 34 printf("%d\n",dp[1][k]); 35 } 36 return 0; 37 } 38
ZOJ 1366
这道题目对于一种产品来说数量有多样,但我们直接用0-1背包做是会超时的,所以先把商品打包在一起,数量由1,2,4,8,16~这样叠加上去,也就是说,即使有1000个数量,也只需要数组用11个地址来保存即可。
再根据0-1背包求解,这里最好把dp[]数组设为1元的,dp过程就逆向思考,不然二元的太耗内存,会不会爆我也没试过
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int cnt;//表示产品的量 6 int price[120],dp[100005]; 7 8 //多重背包转化成0-1背包来求解 9 void change(int k,int pri) 10 { 11 int a=1; 12 price[0]=0; 13 while(k>a){ 14 price[++cnt] = a*pri; 15 k-=a; 16 a<<=1; 17 } 18 price[++cnt] = k*pri; 19 } 20 21 int main() 22 { 23 int cash,n,d,pri; 24 25 while(~scanf("%d%d",&cash,&n)){ 26 cnt=0; 27 memset(dp,0,sizeof(dp)); 28 29 for(int i=0;i<n;i++) 30 { 31 scanf("%d%d",&d,&pri); 32 change(d,pri); 33 } 34 35 for(int i=1;i<=cnt;i++){ 36 for(int j=cash;j>=1;j--){ 37 if(j>=price[i]) 38 dp[j] = max(dp[j],dp[j-price[i]]+price[i]); 39 } 40 } 41 42 printf("%d\n",dp[cash]); 43 } 44 return 0; 45 }
标签:style blog color io os for sp div c
原文地址:http://www.cnblogs.com/CSU3901130321/p/4001903.html