P1036 選數 雙參的dfs

2021-10-08 06:07:34 字數 1704 閱讀 6836

已知 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。現在,要求你計算出和為素數共有多少種。例如上例,只有一種的...