0.題目
小藍正在參與一個現場問答的節目。
活動中一共有 30 道題目,每題只有答對和答錯兩種情況,每答對一題得 10 分,答錯一題分數歸零。
小藍可以在任意時刻結束答題並獲得目前分數對應的獎項,之後不能再答任何題目。
最高獎項需要 100 分,所以到達 100 分時小藍會直接停止答題。
已知小藍最終實際獲得了 70 分對應的獎項,請問小藍所有可能的答題情況有多少種?
本題的結果為一個整數,在提交答案時只輸出這個整數,輸出多餘的內容將無法得分。
1.題解
1.1 線性dp
思路
設定dp[i][j],其中i代表小藍當前做了i題,j表示小藍當前計分的題目數(分數 = j * 10)
注意:
1.小藍可以在任意時刻結束答題並獲得當前分數,所以我要計算出所有當分數
2.(j!=0) dp[i][j] = dp[i-1][j-1]; 如果當前j!=0,也就是不是歸零的情況,從前一次,分數少一分的情況繼承次數即可
(j0) dp[i][0] = dp[i-1][0-9];如果 j0, 說明遇到歸零情況,所有分數全部歸零,包含前一次所有情況,本次分數歸零達到當前情況
3.注意到最高獎項100分,所以j的最大值設定為9,記錄10是沒有意義的,此時已經停止答題,不可能再遇到符合滿70分的情況.
程式碼
#include<bits/stdc++.h>
using namespace std;
int dp[31][10];
int main() {
dp[0][0] = 1;
int ans = 0;
for (int i = 1; i <= 30; i++) {
for (int j = 0; j <= 9; j++) {
if(j) dp[i][j] = dp[i-1][j-1];
else {
for(int k = 0; k <= 9; k++) {
dp[i][j] += dp[i-1][k];
}
}
}
ans += dp[i][7];
}
cout << ans;
}
1.2 dfs暴力搜尋
思路
設定遞迴返回條件和ans+1條件,利用遞迴即可簡單完成
程式碼
#include<bits/stdc++.h>
using namespace std;
int ans = 0;
void dfs(int k, int sc){
if (sc == 70) ans++;
if (k >= 30 || sc >= 100)
return;
dfs(k + 1, sc + 10);
dfs(k + 1, 0);
}
int main() {
dfs(0, 0);
cout << ans;
}