1. 程式人生 > 其它 >劃分為k個相等的子集(dfs+回溯)c語言

劃分為k個相等的子集(dfs+回溯)c語言

技術標籤:習題dfs

文章目錄

題目

給定一個整數陣列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; }

執行結果

在這裡插入圖片描述