hdu 4501 小明系列故事——买年货(三重dp)

小记:真是艹,自己想到了两重dp还写出了状态转移方程,在k的处理我本来是打算dp求完之后,剩下的最大的前k个 加上dp最大值 就是答案,但是那剩下的前k个不晓得怎么搞,所以两重我是解决不了了。 想了我头痛了,百度了一个题目,看到了四个字,立马就顿悟了啊。。。。三重dp!!!日后对于dp的题目还是要多做做,这就是做题不足的后果,再加一重即可,都没有想到,肯定是没加状态,我相信在比赛的时候有专注buff附身 应该绝对肯定能想到!!! 是的,肯定是这样。


思路:dp[k][i][j]  免费拿k个,花i块,花j积分 所能拿到的最大实际价值。

状态转移方程:

dp[k][i][j] = max(dp[k][i][j], dp[k-1][i][j], dp[k][i-price[t]][j], dp[k][i][j - score[t]])  (k > 0, i >= price[t] , j >= score[t],  t = 1,2,3,4....n)

price[t]是第t种用现金要的的钱数,score[t]是第t种用积分兑换需要花的积分数。


代码:

#include <stdio.h>
#include <string.h>
#include <stack>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))

const int MAX_ = 10;
const int MAX = 0x7fffffff;

int price[MAX_*11], score[MAX_*11], real[MAX_*11];
int dp[MAX_][MAX_*11][MAX_*11];

int main() {
    int T;
    int m, k, n, v1,v2;

    while(~scanf("%d%d%d%d",&n,&v1,&v2,&k)) {

        for(int i = 1; i <= n; ++i) {
            scanf("%d%d%d",&price[i],&score[i],&real[i]);
        }
        mst(dp,0);

        for(int i = 1; i <= n; ++i) {
            for(int t = k; t > -1; --t) {
                for(int j = v1; j > -1; --j) {
                    for(int r = v2; r > -1; --r) {
                        int maxm = 0;
                        if(t > 0){
                            maxm = max(dp[t-1][j][r] + real[i],maxm);
                        }
                        if(j >= price[i]){
                            maxm = max(dp[t][j - price[i]][r] + real[i],maxm);
                        }
                        if(r >= score[i]){
                            maxm = max(maxm,dp[t][j][r - score[i]] + real[i]);
                        }
                        dp[t][j][r] = max(maxm,dp[t][j][r]);
                    }
                }
            }

        }
        printf("%d\n",dp[k][v1][v2]);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值