已知 n 個整數 x1,x2,…,xn,以及1個整數k(k3+7+12=22
3+7+19=29
7+12+19=38
3+12+19=34
現在,要求你計算出和為素數共有多少種。
例如上例,只有一種的和為素數:3+7+19=29
鍵盤輸入,格式為:
n,k(1≤n≤20,kx1,x2,…,xn(1≤xi≤5000000)
螢幕輸出,格式為: 1個整數(滿足條件的種數)。
輸入 #1
4 3
3 7 12 19
輸出 #1
1
同為dfs,組合數。所以和之前的全排列問題有相似的地方。
它也有層數限制,也就是找的數的個數。但不同的地方在於
//全排列 n=3
1 2 3
3 2 1
1 3 2
不同順序的同種選擇被看作不同種情況
//組合數 n=3
1 2 3
3 2 1 x
1 3 2 x
被看作同種情況,也就是出現了"1 2 3", 就不能在有乙個組合完全有這3個數
那怎麼處理去除全排列中的「異序同數」呢?
不妨先用現實模擬一下。
資料為「1 2 3 4 」乙個有序列表,寫出它的組合。
很自然就寫出了"1 2 3 " ,"1 2 4 ","1 3 4 ","2 3 4 " ,共4種。
寫的過程中,就發現我是默默按著「要找3個,就先定2個」的思路,從最開頭定下2個,在從其後決定1個。定下的2個用完後,再向後移動這兩個卡位(保證每次移動定下的2個數之和最小,有序時,也就是最靠左)。卡位移動是後卡先動,無法在動後再動前卡。
於是,就發現了移動是有向的,選定的資料都是越來越大。這是一種合理的找法。
在這4種情況中也能發現他們全都是遞增序列。
這才有了想法----增加第二引數。
第二引數保證本次遞迴選數後下次找數隻從比當前數大的數中尋找。所以第二引數在函式中的位置是迴圈招數的初始化,卡在了開頭。
//不同於全排列,從下標3的位置選數後,還可以從1,2位選
//這裡只能按著下標遞增來選 所以引入第二引數來控制迴圈起始下標
#includeusing namespace std;
int n,k,cou=0; //cou 計數器
long long sum=0; //資料和
long long a[50]; //資料陣列
bool flag[50]; //標記
bool isprime(int n) //質數判斷
return 1;
}void dfs(int ceng,int position) //dfs
return; }
for(int i=position;i<=n;i++) //第二引數position }
}int main()
dfs(1,1);
cout《在執行中,正常情況下ceng達到k+1,停止並統計上。
不正常情況,比如找了"3 4 " ,還差一位,但遞迴函式中position已被賦值為5,在迴圈中只是初始化便結束了,走到了dfs函式的最後大括號,故非正常地結束了。(所以缺數的情況也解決了)
洛谷P1036 選數(DFS)
已知 nnn 個整數 x1,x2,xnx 1,x 2,x nx1 x2 xn 以及111個整數kkk k3 7 12 223 7 12 223 7 12 22 3 7 19 293 7 19 293 7 19 29 7 12 19 387 12 19 387 12 19 38 3 12 19 343...
P1036 選數 題解
題目鏈結 已知 nn n 個整數 x1,x2,xnx 1,x 2,x nx1 x2 xn 以及 11 1 個整數 kk k k k n 從 nn n 個整數中任選 kk k 個整數相加,可分別得到一系列的和。例如當 n 4,k 3n 4,k 3n 4,k 3 44 4 個整數分別為 3,7,12,1...
落谷P1036 選數
已知 nn 個整數 x 1,x 2,x nx1 x2 xn 以及11個整數kk k3 7 12 223 7 12 22 3 7 19 293 7 19 29 7 12 19 387 12 19 38 3 12 19 343 12 19 34。現在,要求你計算出和為素數共有多少種。例如上例,只有一種的...