小D知晓的希腊单词个数为n,其中每一个单词有一个复杂度di,表示游人学习这个词语的困难程度。为了在三天中学习强度的差别尽可能地小,小D想知道,是否存在一种将词语划分成三组的方法,让游人在三天中学习词语的复杂度之和相同?
#include<bits/stdc++.h>
using namespace std;
int T,n,d[105],f[105][105];
bool c[105];
int cmp(int x,int y)
{
return x<y;
}
int dp(int x)
{
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
if(!c[i])
for(int j=1;j<=x;j++)
{
if(j>=d[i])
{
f[i][j]=max(f[i-1][j],f[i-1][j-d[i]]+d[i]);
if((f[i-1][j-d[i]]+d[i])>f[i-1][j])
c[i]=1;
else
c[i]=0;
}
else
{
f[i][j]=f[i-1][j];
}
}
if(f[n][x]==x)
return 1;
else
return 0;
}
int main()
{
cin>>T;
while(T--)
{
int sum=0,target=0;
memset(d,0,sizeof(d));
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>d[i];
sum+=d[i];
}
if((!sum%3)||n<=2)
{
cout<<"No"<<endl;
}
else
{
//sort(d+1,d+n+1);//转化为单调增数列
target=sum/3;
/*
问题转化为从d中取数使其值为target
那么能否找最简时一部分成立,
去除已选,然后二部分成立,end
此时target为背包容量
d[i]数值为价值与体积相等的 物品i
*/
//是否到达target
if(dp(target))
{
if(dp(target))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
else
cout<<"No"<<endl;
}
}
return 0;
}