猿宝最近在玩一个猜数字游戏,给定一个数字n,表示答案在1到n之间,每次可以猜一个数字,猜中游戏胜利,但如果猜错了,将要花费所猜数字的金币,并得知是猜大了还是猜小了,但是有k次机会可以免除此花费。猿宝想知道,至少需要准备多少金币能确保获得游戏胜利。
输入两个以空格分割的正整数n k。(n<=300,k<=20)
输出一个正整数表示小明需要准备的金币个数。
3 0
2
先猜数字2,如果答案是2,获得胜利,如果返回猜小了,下次猜1 必定胜利。如果猜大了,下次猜3必定胜利。
3 1
0
先猜数字2,并且使用1次不花费金币的特权,这个时候如果答案是2,获得胜利,如果返回猜小了,只剩下1没猜,下次必定胜利。如果猜大了,只剩下3没猜,下次必定胜利。
使用python运行超时的考生可以尝试切换使用pypy
#include <bits/stdc++.h> using namespace std; int n, m, dp[305][305][25]; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { for (int j = 0; j <= m; j++) { dp[i][i][j] = 0; dp[i][i - 1][j] = 0; } } for (int t = 0; t <= m; t++) { //用了几次机会 for (int i = n; i >= 1; i--) { //L for (int j = i + 1; j <= n; j++) { //R dp[i][j][t] = 0x3f3f3f3f; for (int k = i; k <= j; k++) { //猜k int tmp1 = max(dp[i][k - 1][t], dp[k + 1][j][t]) + k; dp[i][j][t] = min(dp[i][j][t], tmp1); if (t) { int tmp2 = max(dp[i][k - 1][t - 1], dp[k + 1][j][t - 1]); dp[i][j][t] = min(dp[i][j][t], tmp2); } } } } } printf("%d\n", dp[1][n][m]); return 0; }