1. 程式人生 > >(動態規劃)4978:寵物小精靈之收服

(動態規劃)4978:寵物小精靈之收服

能夠 出了 哪些 整數 範圍 -- power 必須 方程

描述

寵物小精靈是一部講述小智和他的搭檔皮卡丘一起冒險的故事。

一天,小智和皮卡丘來到了小精靈狩獵場,裏面有很多珍貴的野生寵物小精靈。小智也想收服其中的一些小精靈。然而,野生的小精靈並不那麽容易被收服。對於每一個野生小精靈而言,小智可能需要使用很多個精靈球才能收服它,而在收服過程中,野生小精靈也會對皮卡丘造成一定的傷害(從而減少皮卡丘的體力)。當皮卡丘的體力小於等於0時,小智就必須結束狩獵(因為他需要給皮卡丘療傷),而使得皮卡丘體力小於等於0的野生小精靈也不會被小智收服。當小智的精靈球用完時,狩獵也宣告結束。

我們假設小智遇到野生小精靈時有兩個選擇:收服它,或者離開它。如果小智選擇了收服,那麽一定會扔出能夠收服該小精靈的精靈球,而皮卡丘也一定會受到相應的傷害;如果選擇離開它,那麽小智不會損失精靈球,皮卡丘也不會損失體力。

小智的目標有兩個:主要目標是收服盡可能多的野生小精靈;如果可以收服的小精靈數量一樣,小智希望皮卡丘受到的傷害越小(剩余體力越大),因為他們還要繼續冒險。

現在已知小智的精靈球數量和皮卡丘的初始體力,已知每一個小精靈需要的用於收服的精靈球數目和它在被收服過程中會對皮卡丘造成的傷害數目。請問,小智該如何選擇收服哪些小精靈以達到他的目標呢?

輸入

輸入數據的第一行包含三個整數:N(0 < N < 1000),M(0 < M < 500),K(0 < K < 100),分別代表小智的精靈球數量、皮卡丘初始的體力值、野生小精靈的數量。
之後的K行,每一行代表一個野生小精靈,包括兩個整數:收服該小精靈需要的精靈球的數量,以及收服過程中對皮卡丘造成的傷害。

輸出

輸出為一行,包含兩個整數:C,R,分別表示最多收服C個小精靈,以及收服C個小精靈時皮卡丘的剩余體力值最多為R。樣例輸入

樣例輸入1:
10 100 5
7 10
2 40
2 50
1 20
4 20

樣例輸入2:
10 100 5
8 110
12 10
20 10
5 200
1 110

樣例輸出

樣例輸出1:
3 30

樣例輸出2:
0 100

提示

對於樣例輸入1:小智選擇:(7,10) (2,40) (1,20) 這樣小智一共收服了3個小精靈,皮卡丘受到了70點傷害,剩余100-70=30點體力。所以輸出3 30
對於樣例輸入2:小智一個小精靈都沒法收服,皮卡丘也不會收到任何傷害,所以輸出0 100

我の思考

這個題目有兩個容量,一個是精力球,一個是皮卡丘的體力值。所以應該要有三重循環...

遇到了runtime error的情況,上網查發現是程序運行到一半被終止了,一般是溢出、除零、越界的問題,後來發現是數組越界了(變量記不準把我轉的有點暈=_=)。

①除以零

②數組越界:int a[3]; a[10000000]=10;

③指針越界:int * p; p=(int *)malloc(5 * sizeof(int)); *(p+1000000)=10;

④使用已經釋放的空間:int * p; p=(int *)malloc(5 * sizeof(int));free(p); *p=10;

⑤數組開得太大,超出了棧的範圍,造成棧溢出:int a[100000000];

我の代碼

#include <iostream>
#include <algorithm>
int num[101];
int wei[101];
int dp[1001][501];  //精力球個數,體力 => 最大捕捉量

using namespace std;

int main()
{
    int n,m,k;
    cin>>n>>m>>k;

    int power = 0;
    for(int i=1;i<=k;i++){
        cin>>num[i]>>wei[i];
    }
    for(int i=1;i<=k;i++){
        for(int j=n;j>=0;j--){
            for(int x=m;x>=0;x--){
                if(j-num[i]>=0&&x-wei[i]>=0)
                    dp[j][x] = max(dp[j][x],dp[j-num[i]][x-wei[i]]+1);
            }
        }
    }

    cout<<dp[n][m]<<" ";

    for(int i=0;i<=m;i++){
        if(dp[n][i]==dp[n][m]){
            cout<<m-i<<endl;
            break;
        }
    }

    return 0;
}

我の小結

做了這幾天的動態規劃,發現有幾個地方最讓人疑惑(???(???(???*)

一個是內層循環應該從最大的開始循環,還是從0開始?

循環,一般就得看是前面的需要後面的,還是後面的需要前面的。

一個是狀態轉移方程中下標的問題,

如果不是容器類,就是前一個推出後一個,如果是,就是自己本身。

一個是最後答案的下標應該是啥,

就按照我們定義的問題去推算。

(動態規劃)4978:寵物小精靈之收服