luogu P1566 加等式 |背包问题方案数

题目描述

对于一个整数集合,我们定义“加等式”如下:集合中的某一个元素可以表示成集合内其他元素之和。如集合{1,2,3}中就有一个加等式:3=1+2,而且3=1+2 和3=2+1是相同的加等式,也是这个集合唯一的加等式。给定一个整数集合,编程找出其所有的加等式的个数

输入格式

第一行为t,表示测试数据组数。(1≤t≤10);

接下来t 行,每行表示一组测试数据。其中第一个数m(1≤m≤30),表示集合元素的个数,接下来m 个不同的整数x 分别表示集合元素(1≤x≤1000)。

输出格式

对于每个输入数据,输出一个整数,表示其中加等式的个数。

.

转化成01背包问题,每个数字是物品,求答案方案数

因为本题必须是两个以上的才能算是加等式,所以最后答案减去n。把n个单独数字组成方案减掉了

.

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
const int N=50,M=1e3+10;
int a[N],f[M];
signed main(){
	int t,n;
	cin>>t;
	while(t--){
		scanf("%lld",&n);
		int Max=0;
		for(int i=1;i<=n;i++){
			scanf("%lld",&a[i]);
			Max=max(Max,a[i]);
		}
		memset(f,0,sizeof(f));
		f[0]=1;
		for(int i=1;i<=n;i++)
		for(int j=Max;j>=a[i];j--)
		f[j]+=f[j-a[i]];
		int ans=-n;
		for(int i=1;i<=n;i++)
		ans+=f[a[i]];
		cout<<ans<<endl;
	}
}
posted @ 2019-09-28 11:09  白木偶君  阅读(175)  评论(0编辑  收藏  举报