简单深搜,主要是这一句 if(!vis[i]&&data[i]<=sum&&(data[i]!=data[i-1]||i==pos))。
确保两个连续的相同的数只有一次机会进入ans[],避免了结果的重复。
code:
#include<cstdio> #include<cstring> int data[ 15] ; int ans[ 15] ; bool vis[ 15] ; bool flag ; int n ; void dfs( int sum, int count, int pos){ if(!sum){ flag = true ; printf( " %d ", ans[ 0]) ; for( int i= 1; i<count; i++) printf( " +%d ", ans[i]) ; printf( " \n ") ; return ; } for( int i=pos; i<n; i++){ if(!vis[i]&&data[i]<=sum&&(data[i]!=data[i- 1]||i==pos)){ vis[i] = true ; ans[count] = data[i] ; dfs(sum-data[i], count+ 1, i+ 1) ; vis[i] = false ; } } } int main(){ int t, i, j ; while(~scanf( " %d%d ", &t, &n)&&t+n){ memset(vis, false, sizeof(vis)) ; for(i= 0; i<n; i++){ scanf( " %d ", &data[i]) ; if(data[i]>t) vis[i] = true ; } printf( " Sums of %d:\n ", t) ; flag = false ; dfs(t, 0, 0) ; if(!flag) printf( " NONE\n ") ; } return 0 ;}