Luogu P1566 【加等式】
阿新 • • 發佈:2018-05-18
ring HR family clu sizeof namespace font ret using
上代碼:
看到這道題,我們首先註意到“找出其所有的加等式的個數”,自然地考慮運用計數DP求出若幹數相加的和的個數
考慮將每個元素排序後DP處理若幹數相加的和的個數
用f[i]表示
對於一個數a[i],對於前i-1個元素選或不選的和j-a[i],選a[i]後的和為j,則組成j-a[i]的方案數會對組成j的方案數做出大小為f[j-a[i]]的貢獻,
所以枚舉i,j,像這樣轉移f[j]+=f[j-a[i]]
考慮加等式的統計:
對於一個整數集合,我們定義“加等式”如下:集合中的某一個元素可以表示成集合內其他元素之和。
對於一個數,我們已經得到它之前所有數選或不選的和等於它的方案數,為了避免漏記,考慮到對於i>j,i一定不會作為j的加等式中的元素出現,所以我們可以在輸入時排序,從小到大DP,對於每個元素a[i],統計它對答案f[a[i]]的貢獻
上代碼:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int t,m,a[40],f[30010],sum;
int main()
{
cin>>t;
while(t--)
{
cin>>m;
sum=0;
for(int i=1;i<=m;i++)
{
cin>>a[i];
sum +=a[i];
}
sort(a+1,a+m+1);
memset(f,0,sizeof(f));
f[0]=1;
int ans=0;
for(int i=1;i<=m;i++)
{
ans+=f[a[i]];
for(int j=sum;j>=a[i];j--)
f[j]+=f[j-a[i]];
}
cout<<ans<<endl;
}
return 0;
}
Luogu P1566 【加等式】