題解 P1036 選數

2022-06-01 21:12:10 字數 2797 閱讀 6774

嗯,新手試煉場的,錯了兩次,對,我是蒟蒻。

因為這道題對我有幫助,所以,它是好題。

錯啦兩次,好尬的。

49——17——100;

不費話了,過程函式與遞推。

當然要遞推:

49分的不說了,從未先編譯一下試試。

跟著題目走,判斷質數。

來一段辣雞**

#includeusing namespace std;

int n,k;

int x[25];

int ans;

bool judge_prime(int x)

} return true;

}int rule(int choose_left_num,int already_sum,int start,int end)

int sum=0;

for(register int i=start;i<=end;i++)

return sum;

}int main()

ans=rule(k,0,0,n-1);

printf("%d",ans);

return 0;

}

遞推函式:

choose_left_num為剩餘的k;

already_sum為前面累加的和;

start和end為全組合(常見)剩下數字的選取範圍;

生成全組合,在過程中逐漸把k個數相加,當選取的數個數為0時,直接返回前面的累加和是否為質數即可;

想了好久才懂得

謝謝題解

nonetheless,

however,

whereas,

but,

就你這種辣雞水平還想遞推,一邊呆著!

所謂「騙分過樣例,暴力出奇蹟」 這段話搜狗拼音第乙個(^-^)

暴搜啊,想什麼哪?

所以:

#includeusing namespace std;

int n,k;

bool notp[10000010];

int a[25];

void caesar(void)

} }return;

}int cae(int x,int sum,int y)

if(n-y老老實實地暴搜。

考慮可能需要進行多次判斷,即使如此優化仍可能超時;

考慮乙個更優的方法:

注意到相加得到的和最大不超過107,可以構造乙個質數表;

每次檢查n是否為質數只需要查表即可.如何構造乙個這樣的質數表呢?

由於乙個質數的任意整倍數(除其自身外)都不是質數,任意乙個整數都可以被表示為某(幾)個質數的乘積,也就是說任意的整數都是某(幾)個質數的整倍數;

因此只需將任意乙個質數的二倍及以上的整倍數標記為"非質數",就可以獲得這樣的一張質數表了;

是這段:

int n,k;

bool notp[10000010];//我叫質數婊,呸,質數表

int a[25];

void caesar(void)//我要創造質數,額(⊙o⊙)…質數表

} }return;

}

這樣一來就更優了.簡單胡亂分析一波:

外層迴圈將重複約107次,若i不是質數則內層將僅進行1次判斷,否則在判斷後還將進行約(107-i)/i次賦值操作;

到目前為止,我們獲得了初始化時間複雜度為o(n),查詢時間複雜度為o(1)的質數表.下面,我們嘗試回到原來的問題,看看我們還缺些什麼?

我們需要從n個數中選出k個並計算它們的和.為了暴搜,我們需要尋找一種方法唯一地定義當前狀態?

很容易注意到,每次只向後看是不會漏選的;

舉例,如當前選到的數中下標最大的是low,那麼選下乙個數的時候只從下標為[low+1,n]的數中選不會導致缺失情況也不會導致重複依然不證明;

因此可以重新定義當前狀態:

還須選i個數,當前的和為sum,當前已經看完了下標為k及以前的數.這樣就確保了每次不需要檢查重複的情況,也不需要管具體選擇了哪些數;

只要一一枚舉k以後的數並遞迴呼叫就可以了,極大的簡化了問題.

遞迴邊界也不難得出:

當還須選0個數的時候,已經選夠了,判斷當前的和是否為質數,如果是返回1,否則返回0;

而非邊界的時候則進行列舉,計算所有情況得到的返回值的和並返回,我們的函式返回值即使在當前限定條件下(從下標大於k的數中選i個數,在sum的基礎上加上選的數的和結果是質數)的情況數;

顯然在主函式中呼叫cae(k,0,0)得到的返回值即為結果

最後還有乙個小小的可行性剪枝:若cal函式中發現n-k

它:#includeusing namespace std;

int n,k;

bool notp[10000010];

int a[25];

void caesar(void)

} }return;

}int cae(int x,int sum,int y)

if(n-y差不多就這樣。

謝謝!人生總有那麼一段大片大片空白的時光。你在等待,你在堅忍,你在靜默。你在等一場春華秋實,你在等新一輪的春暖花開,你在等從未有過的雷霆萬鈞。這靜默的日子有些長,有些悶,但是我也會等下去。我相信人的青春不止有一次,有時候,時光會給你額外的驚喜。

人生にはいつも大きな空白の時間がある。あなたは待っていて、あなたは我慢して、あなたは靜かにしています。あなたは春の美しさを待っていて、あなたは新しい1ラウンドの春の暖かい花が咲いて、あなたはかつてない雷の危機を待っています。この靜かな日は少し長くて、少し退屈ですが、私も待っています。私は人の青春が一度だけではないと信じています。時には、時間はあなたに餘分なサプライズを與えます。

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 選數

洛谷,已知 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...

洛古P1036 選數 題解

我是傳送門 這是一道很經典的深搜與回溯 難度一般 可是就這個 普及 讓本蒟蒻做了一晚上 半個上午 實際我不會深搜回溯,全靠框架 去重 下面讓我分享下本蒟蒻的 全排列 暴搜去重 includeusing namespace std int n,r,ttt n是總數,r是選的數,ttt是答案 int a...