OpenJudge 1757 Magic Pocket (dp)

description

There is a magic pocket with a total volume of 40. Some items can be transformed with this pocket. The total volume of these items must be 40. John now has n items he wants to get, and the volume of each item is a1, a2...an. John can choose some of these items. If the total volume of the selected objects is 40, then John can get these items by using this magical pocket. The question now is how many different ways John has to choose items.

enter

The first line of input is a positive integer n (1 <= n <= 20), indicating the number of different items. In the next n rows, each row has a positive integer between 1 and 40, giving the values ​​of a1, a2...an respectively.

Output

Output the number of different ways to select items.

Sample input

3
20
20
20

Sample output

3

Code

First use recursion to achieve 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 achieve 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;
}

Guess you like

Origin blog.csdn.net/m0_54621932/article/details/114003123