题目意思比较复杂。就是说给你N张牌分别是可能是A.2.3.4.5.6.7.8.9.T.J.Q.K. 其中T.J.Q都是代表数字10,A代表1, K代表任意值。
然后有3 个牌堆(序号为1.2.3),让你把牌按顺序放入牌堆中,每放入一张牌,就得50元,
如果有一个牌堆中已经放入的牌刚刚好是21点,则可以消去这些牌,并且得到牌堆序号*100的钱。
只有当一个牌堆点数超过21时,才不能继续放牌了。
当N张牌放完,或者所有堆都无法放入牌的时候,游戏结束。
输出游戏结束时,你所能获得的最大钱。
构建一个四维的dp[i][g][k][w],代表当有第i张牌时,第一个牌堆为g点,第二个牌堆为k点,第三个牌堆为w点的时候所能得到的最大的钱。
当第i张牌的值为K(这个牌堆能放牌)或者刚刚好可以消去的时候,dp[i+1][0][k][w] = max(dp[i+1][0][k][w] ,dp[i][g][k][w] + 序号*100);
否则dp[i+1][g+v][k][w] = max(dp[i+1][g+v][k][w] ,dp[i][g][k][w] + 50);
To simplify the problem, let's have some assumptions.
The game is played with a standard deck of 54 cards, namely A, 2, 3, 4, 5, 6 , 7, 8, 9, 10 (denoted as T), J, Q, K, Joker (denoted as F. However, the number of cards of a game may be up to 100.
In this game, an Ace values 1 point, the face cards (K, Q and J) value 10 points each and the remaining cards are valued by their numerical values. The joker is a bit different, which will be mentioned later.
There are 3 slots on the table, namely 1x, 2x, 3x.
A slot is available if the total points of the cards on that slot do not exceed 21.
The cards on a slot will be taken away as soon as the total points of cards are 21.
You are asked to put the cards on the table in the given order.
The cards can be put on a slot only if the slot is available.
A joker values as large as possible. In another word, a slot's total value becomes 21 immediately after placing a joker into it.
The game ends if no slot is available or the cards are all used.
You can get 50 dollars if you succeed putting one card onto the table, and 100 dollars multiplied by the number on the slot if you succeed eliminating cards on a slot.
Now your task is to calculate the maximum money you can get.
Input
The input contains multiple test cases!
The first line contains an integer N, denoting the number of cards of this game. The next line contains N characters separated by a single space, denoting the cards.
A line with N = 0 signals the end of the input, which should not be processed.
Output
Output the maximum money you can get in one line for each test case.
Sample Input
1
F
10
J J J J J J J J J J
11
F T J Q K T J Q K T J
2
A A
0
Sample Output
350
450
800
100
Hint
:
In the first case, you can put the joker onto the 3x slot and get 21 points. The total money you get is 50 + 100 * 3 = 350 dollars.
In the second case, you can only put 3 J's onto each slot and no slot is available then. The total money you get is 50 * 9 = 450 dollars.
The third case is a combination of the first two. Note that the first joker can't be counted as 1 point.
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
#define Max_N 105
int dp[Max_N][31][31][31];
int N;
char c;
int v;
int main()
{
while (scanf("%d", &N) && N) {
memset(dp, -1, sizeof(dp));
dp[0][0][0][0] = 0;
for (int i = 0; i < N; i++) {
cin >> c;
if (c == 'F') v = -1;
else if (c == 'A') v = 1;
else if (c == 'J') v = 10;
else if (c == 'Q') v = 10;
else if (c == 'K') v =10;
else if (c == 'T') v = 10;
else v = (int)(c - '0');
for (int k = 0; k < 31; k++)
for (int g = 0; g < 31; g++)
for (int w = 0; w < 31; w++) {
if (dp[i][k][g][w] == -1) continue;
if((v == -1 && k < 21) || v + k == 21)
dp[i+1][0][g][w] = max(dp[i+1][0][g][w], dp[i][k][g][w] + 150);
else if(k < 21) dp[i+1][k+v][g][w] = max(dp[i+1][k+v][g][w], dp[i][k][g][w] + 50);
//else if(k < 21) dp[i+1][22][g][w] = max(dp[i+1][22][g][w], dp[i][k][g][w] + 50);
if((v == -1 && g < 21) || v + g== 21)
dp[i+1][k][0][w] = max(dp[i+1][k][0][w], dp[i][k][g][w] + 250);
else if(g < 21) dp[i+1][k][g+v][w] = max(dp[i+1][k][g+v][w], dp[i][k][g][w] + 50);
//else if(g < 21) dp[i+1][k][22][w] = max(dp[i+1][k][22][w], dp[i][k][g][w] + 50);
if((v == -1 && w < 21) || v + w == 21)
dp[i+1][k][g][0] = max(dp[i+1][k][g][0], dp[i][k][g][w] + 350);
else if(w < 21) dp[i+1][k][g][w+v] = max(dp[i+1][k][g][w+v], dp[i][k][g][w] + 50);
//else if(w < 21) dp[i+1][k][g][22] = max(dp[i+1][k][g][22], dp[i][k][g][w] + 50);
}
}
int ans = 0;
for (int i = 0; i <= N; i++)
for (int k = 0; k < 31; k++)
for (int g = 0; g < 31; g++)
for (int w = 0; w < 31; w++)
ans = max(dp[i][k][g][w], ans);
printf("%d\n", ans);
}
return 0;
}