HDU1963Investment(DP)

简单DP,题解见代码

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #define mem0(a) memset(a,0,sizeof(a))
 5 #define MAX(a, b) (a > b ? a : b)
 6 using namespace std;
 7 
 8 struct BondsV_I
 9 {
10     int Value;
11     int Interest;
12 }Bonds[11];
13 int Amount, Year, BondsNum;
14 int dp[50005];//由于题目说利率不会超过10%,所以也就是不会超过1000*1.1^40,小于50000
15 
16 int main()
17 {
18     int Case;
19     while(~scanf("%d", &Case))while(Case--)
20     {
21         mem0(Bonds);
22         scanf("%d%d", &Amount, &Year);
23         scanf("%d", &BondsNum);
24         for(int i=1;i<=BondsNum;i++)
25         {
26             scanf("%d %d", &Bonds[i].Value, &Bonds[i].Interest);
27             Bonds[i].Value/=1000;//题目说Value都是1000的倍数,所以直接/1000减小复杂度
28         }
29         int ans = Amount;
30         for(int year = 1; year <= Year; year ++)//由于存钱的利息一次性投两年和分开投结果没区别,
31                                                 //甚至一年后可能还会有更好的方式,所以下一年可以只有上一年得到
32         {
33             mem0(dp);//dp保存的是这一年所获得的的利息
34             for(int i=1;i<=BondsNum;i++)//对于每一种方式
35             {
36                 for(int j=Bonds[i].Value;j<=ans/1000;j++)//由于可以选择任意多个,所以是完全背包
37                 {                                        //Value/1000,所以相应的钱/1000
38                     dp[j] = MAX(dp[j-Bonds[i].Value] + Bonds[i].Interest, dp[j]);
39                 }
40             }
41             ans += dp[ans/1000];//更新这一年获得的数目
42         }
43         printf("%d\n", ans);
44     }
45     return 0;
46 }

 

posted @ 2013-08-18 15:36  再见~雨泉  阅读(231)  评论(0编辑  收藏  举报