藍橋杯2023年A組-試題B-有獎問答

DawnTraveler發表於2024-04-06

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;
}

相關文章