poj2063——investment

来源:互联网 发布:大数据包括 编辑:程序博客网 时间:2024/06/05 15:37

题目大意:用一定金额的本金买不同种类的债券,每种债券的价格不同,收益不同,每年的本利和可以做下一年的本金,问给定年份所能得到的最大本利和

输入:测试案例个数

           初始资金(<=1000000) 年数(<=40)

           债券种类数d(1<=d<=10)

           债券i的价格 收益(价格为1000的倍数)

输出:得到的最大本利和

分析:动态规划完全背包问题,债券价格即为物品重量,债券收益即为物品价值,本金就是背包所能承受的重量,每年的收益可以作为下一年的本金,保证每年都获益最大就能得到最后的最优值。注意初始资金过大会导致内存溢出,本金和债券价格都是1000的倍数,所以在这里将本金和债券价格都除以1000来压缩。

           这道题相当于每年是一个背包问题,一共years个背包问题相互关联结合,循环years次求最后解。

           状态dp[j]:本金为j时的最大收益

           结果:sum{dp[si]},s为第i年的本金

           状态转移方程:dp[j]=max{dp[j],dp[j-v[i]]+w[i]}

代码:转载自http://blog.csdn.net/libin56842/article/details/9451843

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <algorithm>  
  4. using namespace std;  
  5.   
  6. struct node  
  7. {  
  8.     int v,w;  
  9. }a[20];  
  10.   
  11. int dp[100000];  
  12.   
  13. int main()  
  14. {  
  15.     int t,n,i,j,k,val,y;  
  16.     scanf("%d",&t);  
  17.     while(t--)  
  18.     {  
  19.         scanf("%d%d",&val,&y);  
  20.         scanf("%d",&n);  
  21.         for(i = 1;i<=n;i++)  
  22.         {  
  23.             scanf("%d%d",&a[i].v,&a[i].w);  
  24.             a[i].v/=1000;//进行压缩  
  25.         }  
  26.         for(i = 1;i<=y;i++)  
  27.         {  
  28.             int s = val/1000;//每年本金都是上一年本金与利息之和  
  29.             memset(dp,0,sizeof(dp));//每年都要重新存利息  
  30.             for(j = 1;j<=n;j++)//完全背包  
  31.             {  
  32.                 for(k = a[j].v;k<=s;k++)  
  33.                 {  
  34.                     dp[k]=max(dp[k],dp[k-a[j].v]+a[j].w);  
  35.                 }  
  36.             }  
  37.             val+=dp[s];//每年的最大本利和  
  38.         }  
  39.         printf("%d\n",val);  
  40.     }  
  41.   
  42.     return 0;  

原创粉丝点击