vijosP1071 新年趣事之打牌

vijosP1071 新年趣事之打牌

链接:https://vijos.org/p/1071

【思路】

   01背包+路径输出。

   用d[][]记录[][]可转移的数目,>=2则输出-1,0输出0,否则输出路径。对于路径可以写一个递归过程print完成。

   本题的数据着实有些坑,需要注意的有数组的范围,使用LL。题目中为什么没有交待?

【代码】

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 
 5 const int maxn = 300+10;
 6 
 7 typedef long long LL;
 8 LL d[maxn][200100];
 9 LL a[maxn];
10 LL n,W;
11 
12 void print(LL n,LL w) {
13     if(n<=0 || !w) return ;
14     if(d[n-1][w]) {
15         print(n-1,w);
16     }
17     else{
18         print(n-1,w-a[n]);
19         cout<<n<<" ";
20     }
21 }
22 
23 int main() {
24     ios::sync_with_stdio(false);
25     cin>>W>>n;
26     LL sum=0;
27     for(int i=1;i<=n;i++) cin>>a[i] , sum+=a[i];
28     W=sum-W;
29     for(int i=0;i<=n;i++) d[i][0]=1;
30     for(int i=1;i<=n;i++)
31        for(int j=0;j<=W;j++)
32         {
33             d[i][j] = d[i-1][j]+d[i-1][j-a[i]];
34         }
35 
36     if(!d[n][W]) cout<<0;
37     else 
38       if(d[n][W]>=2) cout<<-1;
39     else {
40         print(n,W);
41     }
42     return 0;
43 }
原文地址:https://www.cnblogs.com/lidaxin/p/4904869.html