1. 程式人生 > >1071.新年趣事之打牌

1071.新年趣事之打牌

Sample input #2
270
4
100
110
160
170

Sample output #2
-1

Sample input #3
270
4
100
120
160
180

Sample output #3
0

tips:這道題為普通的dp問題,不過裡面需要記錄路徑,這個對我來說比較麻煩,應該算是第一次接觸。。。

       首先,我們這裡的dp陣列只需要記錄所有牌中存在當前重量的組合的個數(ps:對於該題來說,僅需三個狀態,0->無,1->僅有一個,-1->多個),然後就是關於dp的判斷而已,並無難度

     這裡要提到程式碼中一些判斷,由於題目的設定以及資料的提供,我們在某些情況不必一直執行完整的程式碼

    (ps:表達依舊慘淡。。。我的語文多半要掛科,哦對了,我的程式碼有參考網路上的程式碼,看了一遍便自己手打,結果自己開的陣列忘記開大一點,有個return 忘記寫,WA了幾次,慘)

#include <iostream>

usingnamespacestd;

constint maxn=100050;

int Total_W,N;

int dp[maxn],father[maxn],input[200];

bool used[200];

int main()

{

dp[0]=1;

scanf("%d%d",&Total_W,&N);

if (Total_W

==0)  {for (int n=1;n<=N;n++) printf("%d ",n);return0;}

for (int n=1;n<=N;n++) scanf("%d",&input[n]);

for (int n=1;n<=N;n++)

for (int m=Total_W;m>=input[n];m--)

        {

if (dp[m-input[n]]==1)

                {

if (!dp[m]) {dp[m]=1;father[m]=n;}

elsedp[m]=-1;

                }

elseif (dp[m-input[n]]==-1) dp[m]=-1;

        }

if (!dp[Total_W]||dp[Total_W]==-1) {printf("%d",dp[Total_W]);return0;}

int s=Total_W;

while (s!=0)

    {

used[father[s]]=1;

        s-=input[father[s]];

    }

for (int n=1;n<=N;n++)

if (!used[n]) printf("%d ",n);

return0;

}