説明
総量40の魔法のポケットがあります。このポケットで変形できるアイテムもあります。これらのアイテムの総量は40でなければなりません。ジョンには、取得したいアイテムがn個あり、各アイテムのボリュームはa1、a2 ... anです。ジョンはこれらのアイテムのいくつかを選択できます。選択したオブジェクトの総量が40の場合、ジョンはこの魔法のポケットを使用してこれらのアイテムを入手できます。ここで問題となるのは、ジョンがアイテムを選択する方法がいくつあるかということです。
入る
入力の最初の行は正の整数n(1 <= n <= 20)で、さまざまな項目の数を示します。次のn行では、各行に1〜40の正の整数があり、それぞれa1、a2 ... anの値を与えます。
出力
アイテムを選択するさまざまな方法の数を出力します。
サンプル入力
3
20
20
20
サンプル出力
3
コード
最初に再帰を使用して64msを達成します
#include<iostream>
using namespace std;
int a[31];
int work(int aim,int k) //表示用前k个物品去凑aim
{
if(aim==0)
return 1;
if(k==0||aim<0)
return 0;
return work(aim-a[k],k-1)+work(aim,k-1); //用第k个+不用第k个
}
int main()
{
int n;
cin>>a[i];
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
cout<<work(40,n);
return 0;
}
dpは10msを達成します
#include<iostream>
using namespace std;
int a[31];
int f[41][31]; //f[i][j]表示用前j个物品凑i
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=0;i<=n;i++)
f[0][i]=1; //初始,目标为0 记1种
for(int i=1;i<=40;i++)
for(int j=1;j<=n;j++)
{
f[i][j]=f[i][j-1]; //不用第k个
if(i>=a[j])
f[i][j]+=f[i-a[j]][j-1]; //如果第k个小于目标,加上用第k个的
}
cout<<f[40][n];
return 0;
}