題解 P2760 【科技莊園】
題目出處https://www.luogu.org/problemnew/show/P2760
蒟蒻第一次用,寫的不好望各位奆佬包涵!QWQ
題目背景
Life種了一塊田,裏面種了有一些桃樹。
Life對PFT說:“我給你一定的時間去摘桃,你必須在規定的時間之內回到我面前,否則你摘的桃都要歸我吃!”
PFT思考了一會,最終答應了!
由於PFT的數學不好!它並不知道怎樣才能在規定的時間獲得最大的價值,
由於PFT不是機器人,所以他的體力並不是無限的,他不想摘很多的桃以至體力爲0,而白白把桃給Life。同時PFT每次只能摘一棵桃樹,,每棵桃樹都可以摘K次(對於同一棵桃每次摘的桃數相同)。每次摘完後都要返回出發點(PFT一次拿不了很多)即Life的所在地(0,0){試驗田左上角的桃座標是(1,1)}。
PFT每秒只能移動一個單位,每移動一個單位耗費體力1(摘取不花費時間和體力,但只限上下左右移動)。
題目描述
輸入輸出格式
輸入格式:
第一行:四個數爲N,M,TI,A 分別表示試驗田的長和寬,Life給PFT的時間,和PFT的體力。
下面一個N行M列的矩陣桃田。表示每次每棵桃樹上能摘的桃數。
接下來N行M列的矩陣,表示每棵桃最多可以採摘的次數K。
輸出格式:
一個數:PFT可以獲得的最大的桃個數。
輸入輸出樣例
輸入樣例#1:
4 4 13 20 10 0 0 0 0 0 10 0 0 0 10 0 0 0 0 0 1 0 0 0 0 0 2 0 0 0 4 0 0 0 0 0
輸出樣例#1:
10
說明
樣例說明:
可以摘到1次(1,1)和1次(2,3),體力和時間不滿足再摘桃了。
範圍:
對於M,N,TI,A 10<=30%<=50 10<=100%<=100
對於K 10<=100%<=100
保證結果在long int範圍內
別的不說,上代碼!
還是說一下吧:
這道題第一眼看到覺得是個二維揹包啊!
但是,注意,童鞋移動的速度和消耗的體力是一樣的!
於是,將體力和時間求最小就是揹包的容量了。
不過注意此童鞋的體力是要雙份的(來回),而且到達目的地的時候一定要活着(要不然桃子也不是自己的)
於是便有:
t = min(t-1,time);
自認爲代碼十分易懂且代碼註釋十分詳細
於是便不說一些了,看代碼便是!!
#include<iostream>
using namespace std;
int i,j,k,l,n,m,v,u,g,tim;
int f[11000],s[1100][1100],q[1100][1100];
int w[1110000],c[1100000];
int num=1,ans;
int main()
{
//乍一看,有一個想法,這不是一個二維揹包咩?
//但這題有個很好的BUG,其實也不算了,就是一個很好玩的條件
//PET童鞋每秒移動一個單位,每移動一個單位耗一點體力
//這就成了01了!
//對了,還有,注意PET童鞋比較那啥,他的路程是要跑兩次的!
int t;
cin>>n>>m>>tim>>t;//矩陣長 寬 時間 體力
f[0]=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>s[i][j];
}//能摘的桃數量
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>q[i][j];//能摘的次數
if(s[i][j]>0)//如果這棵樹能摘
{
for(int v=num;v<=num+q[i][j];v++)
//有一點提醒一下,就是上面那句for循環,注意num的值!
//num是可摘總數 (物品數量!)
{
w[v]=(i+j)*2;//w[]是花費(可以這麼說),就是物體體積了啦!
c[v]=s[i][j]; //提一下,c[]爲價值,就不說了哈!
}
}num+=q[i][j];//桃紙的總數
}
}
t=min(t-1,tim);//不多解釋 ,前面有講;
for(i=1;i<=num;i++)
for(j=t;j>=w[i];j--)
{
if(j-w[i]<0) break;//這一部分不解釋
else
f[j]=max(f[j],f[j-w[i]]+c[i]);//狀態轉移大方程,不多解釋
}
cout<<f[t]<<endl;
}
完結散花!!
QWQ~~~