d280: 骰子問題
Tags: dp
出處:https://zerojudge.tw/ShowProblem?problemid=d280
提交:https://zerojudge.tw/Submissions?problemid=d280&account=allllllan123456
問題:給定 $N\in[1,20]$ 個骰子,請問這些骰子能一同擲出總和為 $M\in[N,6N]$ 點的方法數有多少。
解法:就經典的 DP,把問題拆成最後一個骰子與前面所有骰子兩組來看,如果我最後一個骰子只擲出 1 點,那前面所有骰子就必須擲出 M-1 點;如果我最後一個骰子只擲出 2 點,那前面所有骰子就必須擲出 M-2 點,依此類推,所以就根據最後一個骰子的點數進行方法數的討論與加總即可。
1#include <bits/stdc++.h>
2using namespace std;
3
4long long DP[21][121];
5
6long long f(int n, int m) {
7 if (m<n || m>6*n) return 0;
8 if (n == 1) return 1;
9 if (DP[n][m]) return DP[n][m];
10 return DP[n][m] = f(n-1, m-1) + f(n-1, m-2) + f(n-1, m-3)
11 + f(n-1, m-4) + f(n-1, m-5) + f(n-1, m-6);
12}
13
14int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); // IO 優化
15 int T; cin >> T;
16 while (T--) {
17 int a, b; cin >> a >> b;
18 cout << f(a,b) << '\n';
19 }
20 return 0;
21}