给出一个数t,n,然后后面有n个数。
问:从这n个数里面能不能挑出一些数,使得和为t,注意输出顺序。
Sample Input
4 6 4 3 2 2 1 1
5 3 2 1
1 400 12 50 50 50 50 50 50 25 25 25 25 25 25
0 0
Sample Output
Sums of 4:
4
3+1
2+2
2+1+1
Sums of 5:
NONE
Sums of 400:
50+50+50+50+50+50+25+25+25+25
50+50+50+50+50+25+25+25+25+25+25
要满足这种输出顺序,知道预先将数组从大到小排列就OK了。
dfs(int cnt,int cnr,int sum)
cnt 表示当前ans数组放进了多少个数字,
cur 表示当前加进去的数在a数组的位置
sum 表示当前的和
用一个pre防止相同的数在相同条件下加进去。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=1010; 6 const int inf=0x3f3f3f3f; 7 int a[maxn]; 8 int t,n; 9 bool vis[maxn]; 10 int ans[maxn]; 11 bool flag; //判断有没有解 12 bool cmp(int b,int c) 13 { 14 return b>c; 15 } 16 void dfs(int cnt,int cur,int sum) 17 { 18 if(sum>t||cnt>n) 19 return ; 20 ans[cnt]=a[cur]; 21 if(sum==t) 22 { 23 for(int i=1;i<cnt;i++) 24 printf("%d+",ans[i]); 25 printf("%d\n",ans[cnt]); 26 flag=true; 27 return ; 28 } 29 int pre=inf; //防止相同的数在相同的条件下加进去 30 for(int i=cur+1;i<=n;i++) 31 { 32 if(!vis[i]&&a[i]!=pre){ 33 vis[i]=true; 34 pre=a[i]; //及时更新 35 dfs(cnt+1,i,sum+a[i]); 36 vis[i]=false; //回溯 37 } 38 } 39 } 40 int main() 41 { 42 while(scanf("%d%d",&t,&n)) 43 { 44 if(t==0&&n==0) 45 break; 46 for(int i=1;i<=n;i++) 47 scanf("%d",&a[i]); 48 memset(vis,false,sizeof(vis)); //初始化 49 sort(a+1,a+n+1,cmp); 50 a[0]=inf; 51 flag=false; //假设没有解,找到解后为true 52 printf("Sums of %d:\n",t); 53 int pre=inf; 54 for(int i=1;i<=n;i++) 55 { 56 if(a[i]!=pre) 57 { 58 vis[i]=true; 59 dfs(1,i,a[i]); 60 vis[i]=false; //回溯 61 pre=a[i]; 62 } 63 } 64 if(!flag) 65 printf("NONE\n"); 66 } 67 return 0; 68 }
时间: 2024-10-13 05:51:24