首页 > 代码库 > DP 简单题目练习

DP 简单题目练习

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 }

 

DP 简单题目练习