新年趣事之打牌

这题比较方便的一点是不用每次输出多条路径,所以这题就变得简单化了,统计一下方案数就可以了。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1e7+10;

int dp[MAXN],a[MAXN],path[MAXN];
int n,w,sum=0,m;

void print(int j) {
    if (!j) {
        return;
    }
    print(j-a[path[j]]);
    printf("%d",path[j]);
    if (j!=m) printf(" ");
}

int main() {
    cin>>w>>n;
    for (int i=1;i<=n;i++) {
        cin>>a[i];
        sum+=a[i];
    }
    m=sum-w;
    dp[0]=1;
    /*
        虽然这样不同的方案可能包含同一种物品
        但是即使如此也是不同的方案
    */
    for (int i=1;i<=n;i++) {
        for (int j=m;j>=a[i];j--) {
            dp[j]+=dp[j-a[i]];
            if (dp[j]>5) dp[j]=2;
            if (dp[j-a[i]]) path[j]=i;
        }
    }
    if (!dp[m]) cout<<0<<endl;
    else if (dp[m]>1) cout<<-1<<endl;
    else {
        print(m);
    }
    return 0;
}
posted @ 2020-04-06 16:21  xyee  阅读(300)  评论(0编辑  收藏  举报