poj2063 Investment(完全背包)

来源:互联网 发布:中性笔成分知乎 编辑:程序博客网 时间:2024/06/07 07:31


http://poj.org/problem?id=2063

题意:Jone想做一笔投资。现在他有一笔初始资金,准备做几年的投资。他想买债券,债券的归还期为一年,也就是说每到一年他得回收本金与利息,再次购买新的债券。债券有n种,每种的价格和利息(每年)都列举出来。求最大收益。


ps:好难懂的题意,不过很贴近于生活。


思路:由于想买的债券每种都是无限数量,所以是完全背包求不超过每年初始资金的最大利息。由于债券可以被1000整除,所以背包中原始资金的容量也应该除以1000。这里dp的最大范围比较难算,1 000 000/1000=1000后每年利息不超过10%,也就是说40年后至少也有100*40=4000的利息,不过以防万一,还是尽量往大开好了。这里RE了一次。另外,这题背包是未装满,初始dp为0。还有,用二维的话会爆内存,所以一般情况还是能用一维就用一维吧。


#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;typedef long long LL;const int N = 46005;const int INF = 0x3f3f3f3f;int dp[N];int main(){   // freopen("in.txt", "r", stdin);    int t, V, n, time;    int cost[N], weight[N];    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &V, &time);        scanf("%d", &n);//物品数量        for(int i = 1; i <= n; i++)        {            scanf("%d%d", &cost[i], &weight[i]);            cost[i]/=1000;        }        int V0 = V;        int inte = 0;//利息        for(int k = 1; k <= time; k++)        {            memset(dp, 0, sizeof(dp));//未装满            V += inte;            V0 = V/1000;            for(int i = 1; i <= n; i++)                for(int j = cost[i]; j <= V0; j++)                {                    dp[j] = max(dp[j], dp[j-cost[i]]+weight[i]);                }            inte = dp[V0];        }        printf("%d\n", V+inte);    }    return 0;}


想了想还是把爆内存的二维贴上来吧。

#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;typedef long long LL;const int N = 4600;const int INF = 0x3f3f3f3f;int dp[N][N];int main(){ //   freopen("in.txt", "r", stdin);    int t, V, n, time;    int cost[N], weight[N];    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &V, &time);        scanf("%d", &n);//物品数量        for(int i = 1; i <= n; i++)        {            scanf("%d%d", &cost[i], &weight[i]);            cost[i]/=1000;        }        int V0 = V;        int inte = 0;//利息        for(int k = 1; k <= time; k++)        {            memset(dp, 0, sizeof(dp));//未装满            V += inte;            V0 = V/1000;            for(int i = 1; i <= n; i++)                for(int j = 0; j <= V0; j++)                {                    if(j < cost[i]) dp[i][j] = dp[i-1][j];                    else dp[i][j] = max(dp[i-1][j], dp[i][j-cost[i]]+weight[i]);                }            inte = dp[n][V0];            printf("[%d]\n", inte);        }        printf("%d\n", V+inte);    }    return 0;}



0 0