劃分為k個相等的子集(dfs+回溯)c語言
阿新 • • 發佈:2020-12-30
文章目錄
題目
給定一個整數陣列nums和一個正整數k,找出是否有可能把這個陣列分成k個非空子集,其總和都相等。
例項1:
輸入:nums=[4,3,2,3,5,2,1],k=4
輸出:True
說明:有可能將其分成4個子集(5),(1,4),(2,3),(2,3)等於總和
c語言程式碼
#include <stdio.h>
int nums[101];//存放所有的數
int sum=0;//存放所有的數的和
int average=0;//每個集合內所有數的和
int n;//總共多少個數
int k;//k個集合
int max= 0; //所有的數裡面的最大值
bool visited[101];//標記該數是否被選擇
bool dfs(int setNums,int curSum,int start)
{
if(setNums==0) //當前所有的集合都分配到了
return true;
if(curSum==average)//當前該集合分到了average,該對下一個集合進行分配了
return dfs(setNums-1,0,0);
for(int i=0;i<n;i++)
{
if(!visited[i]&&curSum+nums[i]<=average)//該數未被選擇,並且能夠放進當前集合
{
visited[i]=true;
if(dfs(setNums,curSum+nums[i],i+1)) //加入該數後若分配成功返回true
//當為該集合找下一個數時直接可以從i+1往後找節省時間
return true;
visited[i]=false;
}
}
return false;//所有的數都遍歷了,未分配成功返回false
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d" ,&nums[i]);
sum+=nums[i];
if(nums[i]>max)
max=nums[i];
}
scanf("%d",&k);
average=sum/k;
if(sum%k!=0||max>average) //所有的和不能夠分成k個相等的集合,集合裡面有最大值大於平均值
{printf("flase");
return 0;
}
if(dfs(k,0,0))
{
printf("true");
return 0;
}
printf("false");
return 0;
}