poj2063 Investment(完全背包)


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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值