Life種了一塊田,裏面種了有一些桃樹。
Life對PFT說:“我給你一定的時間去摘桃,你必須在規定的時間之內回到我面前,否則你摘的桃都要歸我喫!”
PFT思考了一會,最終答應了!
由於PFT的數學不好!它並不知道怎樣才能在規定的時間獲得最大的價值,
由於PFT不是機器人,所以他的體力並不是無限的,他不想摘很多的桃以至體力爲0,而白白把桃給Life。同時PFT每次只能摘一棵桃樹,,每棵桃樹都可以摘K次(對於同一棵桃每次摘的桃數相同)。每次摘完後都要返回出發點(PFT一次拿不了很多)即Life的所在地(0,0){試驗田左上角的桃座標是(1,1)}。
PFT每秒只能移動一個單位,每移動一個單位耗費體力1(摘取不花費時間和體力,但只限上下左右移動)
https://www.luogu.org/problemnew/show/P2760
這題真是厲害!!!
這題乍一看像是個二維揹包;但發現每次採摘都要回起點,且每個樹可以採好幾次;好像是個01揹包哈哈。
那麼物品體積就是從起點到這個點的距離*2,就是(i+j)*2;
每件物品的價值就是桃子數量;
物品數量就是所有桃樹可採摘次數之和;
#include <iostream>
#include <cstdio>
using namespace std;
int n,m,t,tl;
int a[1101][1101],b[1101][1101];
int w[1110001],v[1100001],f[11001];
int num=0;
int main()
{
cin>>n>>m>>t>>tl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>b[i][j];
if(a[i][j]>0){
for(int k=1;k<=b[i][j];k++){
w[++num]=2*(i+j);
v[num]=a[i][j];
}
}
}
}
t=min(tl-1,t);
f[0]=0;
for(int i=1;i<=num;i++){
for(int j=t;j>=w[i];j--){
if(j-w[i]<0) break;
else f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
cout<<f[t];
return 0;
}