可持久化Trie+堆优化 OR Trie树上求XOR第K大 ---- P5283 [十二省联考2019]异或粽子

(一)Ubuntu18.04下的Hadoop3.2.2详细安装与分布式集群搭建

  返回  

P5662 [CSP-J2019] 纪念品题解

2021/8/21 19:16:29 浏览:

题目链接

题意

已知 T T T N N N种纪念品每天的价格,最初有 M M M个金币,求经过N天的交易后,最多有多少个金币?每天可以交易无限次,每种物品可以买卖无限个,只要金币足够。每天卖出纪念品换回的金币可以立即用于购买纪念品,当日购买的纪念品也可以当日卖出换回金币。

题目分析

这是一个完全背包问题。

由于每天卖出纪念品换回的金币可以立即用于购买纪念品,当日购买的纪念品也可以当日卖出换回金币,因此不必考虑当天结束后,手里有多少金币和多少物品,统一用金币数量来衡量,那物品的价值价值由什么决定?答案是明天的价格

那么,每天的交易可以转化为完全背包问题:

  • 背包容量——昨天交易完成后的最大金币数量
  • 物品体积 C i C_i Ci——物品 i i i 今天的价格
  • 物品价值 V i V_i Vi——物品 i i i 明天的价格

将第 1 1 1 T − 1 T-1 T1 天,每天跑一遍完全背包,答案。
注意每天开始前的初始化。
注意优化完全背包。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxt = 100+10;
const int maxn = 100+10;
const int maxm = 1000+10;
const int maxp = 10000+10;
int T,N,M;
int p[maxt][maxn];
int dp[maxp];
inline int cal(){
    for(int t = 1;t<T;t++){ //每一天跑一遍完全背包
        for(int j = 0;j<=M;j++) dp[j] = j;  //初始化
        for(int i = 1;i<=N;i++){
            for(int j = p[t][i] ;j<=M;j++)
                dp[j] = max(dp[j],dp[j-p[t][i]]+p[t+1][i]);
        }
        M = dp[M];
    }
    return M;
}
int main(){
    scanf("%d%d%d",&T,&N,&M);
    for(int t = 1;t<=T;t++){
        for(int i = 1;i<=N;i++){
            scanf("%d",&p[t][i]);
        }
    }
    cout<<cal()<<endl;
    return 0;
}

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号