Date:2022.03.14
题目描述
对于一个整数集合,我们定义“加等式”如下:集合中的某一个元素可以表示成集合内其他元素之和。如集合{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)。
输出格式
对于每个输入数据,输出一个整数,表示其中加等式的个数。
输入输出样例
输入 #1复制
3
3 1 2 3
3 1 2 5
6 1 2 3 5 4 6
输出 #1复制
1
0
7
思路:首先集合有互异性,因此不存在两个相同元素,自然每个元素只能被选一次。问题即变为:f[i]<==>f[i]<==>f[i]<==>给定n个物品选择若干个(每个物品只能选一次),能凑出和为iii的方案数。
状态转移:f[j]+=f[j−a[i]];f[j]+=f[j-a[i]];f[j]+=f[j−a[i]];
初始状态:f[0]=1;f[0]=1;f[0]=1;【一个都不选自然和为0,方案数为1】。
结束状态:f[a[1]]+f[a[2]]...+f[a[n]]−n;f[a[1]]+f[a[2]]...+f[a[n]]-n;f[a[1]]+f[a[2]]...+f[a[n]]−n;【即每个元素都可能被凑出;−n-n−n是因为每次凑出了f[a[i]]+=f[0]f[a[i]]+=f[0]f[a[i]]+=f[0],而每个数单独自己不能是加等式,但却计数计入了其中。】
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
typedef long long LL;
LL n,m,p,k,t,a[N],f[N];
int main()
{
cin>>t;
while(t--)
{
memset(f,0,sizeof f);f[0]=1;
cin>>n;for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
for(int j=1000;j>=a[i];j--)
f[j]+=f[j-a[i]];
LL res=0;
for(int i=1;i<=n;i++)
res+=f[a[i]];
cout<<res-n<<endl;
}
return 0;
}
这篇博客介绍了一个关于整数集合中加等式的动态规划解决方案。通过给出的输入格式和样例,作者详细解释了如何计算集合中加等式的数量。思路包括状态转移方程和初始及结束状态,并提供了相应的C++代码实现。
1931

被折叠的 条评论
为什么被折叠?



