就是01背包小小变形一下就不太会做了。。。。
思路:
当前和的方案数等于当前和减当前和当去当前正数的方案数,如:当前正数为2,和为5的方案数就等于3(5-2)的方案数,和为3的方案数又等于1(3-2)的方案数。又因为在每一种方案中每个数字只能使用一次,所以采用01背包。
状态转移方程式:dp[j]+=dp[j-w[i]]。
ac代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
int w[25]; int dp[1005]; int n,m;
void dp_(){
for(int i=1;i<=n;i++){
for(int j=m;j>=w[i];j--){
dp[j]+=dp[j-w[i]];
}
}
}
signed main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i];
dp[0]=1;//当组成数为0时的方法为1.
dp_();
cout<<dp[m]<<endl;
return 0;
}