1. 程式人生 > 其它 >寵物小精靈之收服(等級考試4級 2021-03 T1)

寵物小精靈之收服(等級考試4級 2021-03 T1)

題目:

此題目可轉化為 01揹包問題

dp[ i ] [ j ] [ l ] 表示i個精靈球、j點體力、l 個精靈時最多收復精靈的個數。

注意事項:開三維陣列一定要貼著給的資料開,本題中開dp[1001][501][101],否則容易爆。

遍歷範圍:

  i:1~n

  j:1~m

  l:1~k

w[l]: 需要消耗的精靈球數量

v[l]:需要消耗的體力值

狀態轉移方程:

if(i>=w[l]&&j>v[l]) //餘下的精靈球數量足夠、體力也足夠。

{

  dp[i][j][l]=max(dp[i-w[l]][j-v[l]][l-1]+1,dp[i][j][l-1]);// 前者為取第l 個精靈 後者為不取。

}

else

{

  dp[i][j][l]=dp[i][j][l-1];

}

最後輸出捕捉最多精靈後剩餘的最大體力。

k1指用掉多少點能量。

k1從m開始向下減,直到dp[n][k1][l]與dp[n][m][k]不相同時輸出m-k1即餘下的體力。

程式:

#include<bits/stdc++.h>
using namespace std;
int dp[1001][501][101];
int main()
{
    int n,m,k,w[1010],v[1010];
    cin>>n>>m>>k;
    for(int i=1;i<=k;i++)
    {
        scanf(
"%d%d",&w[i],&v[i]); } int m2=m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { for(int l=1;l<=k;l++) { if(i>=w[l]&&j>v[l]) { if(dp[i-w[l]][j-v[l]][l-1]+1>dp[i][j][l-1
]) { m2-=v[l]; dp[i][j][l]=dp[i-w[l]][j-v[l]][l-1]+1; } else { dp[i][j][l]=dp[i][j][l-1]; } } else { dp[i][j][l]=dp[i][j][l-1]; } } } } cout<<dp[n][m][k]<<" "; int k1=m; while(k1>0&&dp[n][k1][k]==dp[n][m][k]) k1--; cout<<m-k1; return 0; }