题目:
分析:
先判断4的倍数。
和背包一样,拿三次。
代码1,直接暴力回溯,超时:
int k;
bool f(vector<int> nums,vector<int> n,int sum,int c)
{
if(sum==0) {
if(c==3) {
return 1;
}
c++;
if(f(nums,n,k,c)) return 1;
return 0;
}
for(int i=0;i<nums.size();i++)
{
if(sum>=nums[i]&&n[i]!=1)
{
n[i]=1;
if(f(nums,n,sum-nums[i],c)) return 1;
n[i]=0;
}
}
return 0;
}
int main()
{
vector<int> nums;
if(nums.size()<4) return 0;
vector<int> n(nums.size(),0);
int all=0;
for(int i=0;i<nums.size();i++) all+=nums[i];
if(all%4!=0) return 0;
k=all/4;
return f(nums,n,k,0);
}
代码2:改变回溯,倒着拿的优势—贪心,给再次拿更大的可能是最终结果。
int k;
bool f(vector<int> nums,vector<int> &n,int sum)
{
cout<<sum<<" ";
if(sum==0) {
return 1;
}
int last=1<<30;
for(int i=0;i<nums.size();i++)
{
if(sum>=nums[i]&&n[i]!=1)
{
if(nums[i]==last) continue;
last=nums[i];
n[i]=1;
if(f(nums,n,sum-nums[i])) return 1;
n[i]=0;
}
}
return 0;
}
int main()
{
vector<int> nums;
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
//[3,1,3,3,10,7,10,3,6,9,10,3,7,6,7]
if(nums.size()<4) return 0;
vector<int> n(nums.size(),0);
int all=accumulate(nums.begin(),nums.end(),0);
if(all%4!=0) return 0;
k=all/4;
sort(nums.begin(),nums.end(),greater<int>());
for(int i=0;i<3;++i)
{
if(!f(nums,n,all/4)) cout<<0;
}
cout<<1;
}