題目描述: https://www.luogu.org/problem/P5662?contestId=24102
完全揹包問題,因數據量不大,可以先用map二維數組把輸入全存下來。
對某一天來說,把數據處理成完全揹包問題:其中,買某一個物品需多少錢,相當於揹包問題中的weigth;
明天該物品價錢-今天當前物品價錢就相當於是價值value。動態規劃求出在當前手裏有的M金幣下,明天都賣掉最多能賺多少,隨後M=M+dp[M]。
/*
T未來天數 N紀念品數量 M現在擁有的金幣數量
*/
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int map[105][105];
struct node{
int w,v;
//weigth記錄買當前物品需花掉的錢,value記錄能賺多少錢 (下一天的價格-今天的價格)
}point;
int solve(vector<node>& v,int M){
int dp[10005]={0};
int len=v.size();
if(!v.empty()){
for(int j=0;j<len;j++){
for(int i=M;i>=0;i--){//滾動數組,完全揹包
int max_tmp=-1;
int len_tmp=i/v[j].w;
for(int k=0;k<=len_tmp;k++){
max_tmp=max(max_tmp,k*v[j].v+dp[i-k*v[j].w]);
dp[i]=max_tmp;
}
}
}
return dp[M]+M;
}else
return M;
}
vector<node> q;
int main() {
//數據初始化
freopen("jnp1.in","r",stdin);
int T,N,M,tmp;
scanf("%d %d %d",&T,&N,&M);
for(int j=0;j<T;j++){
for(int i=0;i<N;i++){
scanf("%d",&map[j][i]);
}
}
//邏輯處理
for(int j=0;j<T-1;j++){//注意j的範圍
for(int i=0;i<N;i++){
tmp=map[j+1][i]-map[j][i];//買當前物品到明天能賺多少錢
if(tmp>0){//若能賺錢,入隊
point.w=map[j][i]; point.v=tmp;
q.push_back(point);
}
}
M=solve(q,M);//完全揹包,更新一下擁有的最大錢數M
q.clear();
}
printf("%d\n",M);
return 0;
}