首页 > ACM题库 > HDU-杭电 > HDU 2905-Blackjack[解题报告]HOJ
2014
02-21

HDU 2905-Blackjack[解题报告]HOJ

Blackjack

问题描述 :

In the game of blackjack you play against the dealer. Blackjack is played with a regular deck of playing cards containing the cards 2, 3, 4, 5, 6, 7, 8, 9, 10,jack, queen, king and ace of various suits. (However the suits do not infiuence the game in any way.) The cards 2 through 10 have value 2 through 10. The jack, queen, and king cards have value 10. Each individual ace can count as either 1 or 11. We define the low value of a player as the lowest possible sum of the values of all the cards of a player, thus counting all aces as 1. The high value of a hand is the highest possible sum of the values that is still below 22, counting aces as 1 or 11 accordingly.

In this problem a basic blackjack variant is considered; there is no splitting, doubling, insurance or "blackjack".

The goal of the game is to maximize your (expected) profit or mimimize your (even more expected) losses. One hand of the game is played as follows:

You place a bet of x euros;

You get one card, then the dealer gets one card;

You get a second card, and finally the dealer gets a second card;

As long as your low value is below 22, you have two options:

"Hit"- take one extra card from the deck;

"Stand"- take no more cards.

If your low value is above 21, you lose bet and the hand ends immediately.

Now the dealer will play his cards;

As long as the high value of the dealer is below 17, the dealer takes an extra card from the deck;

If the low value of the cards of the dealer is above 21, you receive 2x euros, making a profitof x euros;

If the high value of the dealer is greater than than your high value, you lose the bet;

If the high value of the dealer equals your high value, the bet is returned to you;

If the high value of the dealer is less than than your high value, you receive 2x euros, making a profit of x euros;

At the end of the hand, all used cards are placed on a "discard pile" and will not return into play.

If at any time there are no cards left in the deck and the dealer has to get another card or you choose to get another card then the current hand is disregarded and the bet is returned to you.

In this problem, the sequence of cards left in the deck is known to you. You have to write a program to help yourself play optimally (ie. maximize profit).

输入:

The first line of input consists of the integer number n, the number of test cases;

Then, for each test case:

One line with three integers 0 <=c<=10,000 and 0 <= p <= q<=100: the number of cards left in the deck, the minimum bet and the maximum bet respectively;

[c/60] lines with a total of c characters (’2′-’9′, ‘T’, ‘J’, ‘Q’, ‘K’, ‘A’), representing the sequence of cards in the deck. The first character on the first line represents the first card that will come off the deck. Only the last line may contain less than 60 characters.

输出:

The first line of input consists of the integer number n, the number of test cases;

Then, for each test case:

One line with three integers 0 <=c<=10,000 and 0 <= p <= q<=100: the number of cards left in the deck, the minimum bet and the maximum bet respectively;

[c/60] lines with a total of c characters (’2′-’9′, ‘T’, ‘J’, ‘Q’, ‘K’, ‘A’), representing the sequence of cards in the deck. The first character on the first line represents the first card that will come off the deck. Only the last line may contain less than 60 characters.

样例输入:

1
4 1 15
TTA8

样例输出:

15

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int oo = 1000000000;
char s[10010], cards[2][50];
int dp[10010], nc[2], value[300];

void update(int& x, int y)
{
 if (y > x) x = y;
}

int lv(int u)
{
 int ret = 0;
 for (int i = 0; i < nc[u]; ++i) ret += value[cards[u][i]];
 return ret;
}

int hv(int u)
{
 int ret = 0, x = 0;
 for (int i = 0; i < nc[u]; ++i)
 if (cards[u][i] == 'A') ++x, ret += 11;
 else ret += value[cards[u][i]];
 while (ret > 21 && x > 0) ret -= 10, --x;
 return ret;
}

void getCard(int u, int& cur)
{
 cards[u][nc[u]++] = s[cur++];
}

int main()
{
 for (int i = '2'; i <= '9'; ++i) value[i] = i-'0';
 value['T'] = value['J'] = value['Q'] = value['K'] = 10;
 value['A'] = 1;
 int T, n, p, q, l[2];
 scanf("%d", &T);
 while (T--) {
 scanf("%d%d%d", &n, &p, &q);
 int cur = 0;
 while (cur < n) {
 scanf("%s", s+1+cur);
 cur += strlen(s+1+cur);
 }
 for (int i = 1; i <= n; ++i) dp[i] = -oo;
 dp[0] = 0;
 for (int i = 0; i < n; ++i) if(dp[i] != -oo) {
 if (i+4 > n) {
 update(dp[n], dp[i]);
 continue;
 }
 int cur = i + 1;
 nc[0] = nc[1] = 0;
 getCard(0, cur);
 getCard(1, cur);
 getCard(0, cur);
 getCard(1, cur);
 l[0] = value[cards[0][0]]+value[cards[0][1]];
 while(1) {
 if (l[0] > 21) {
 update(dp[cur-1], dp[i] - p);
 break;
 }
 int pre = cur;
 nc[1] = 2;
 while (pre <= n && hv(1) < 17) getCard(1, pre);
 if (hv(1) < 17) update(dp[n], dp[i]);
 else {
 int h[2] = {hv(0), hv(1)};
 if (lv(1) > 21) update(dp[pre-1], dp[i] + q);
 else if (h[0] > h[1]) update(dp[pre-1], dp[i] + q);
 else if (h[0] < h[1]) update(dp[pre-1], dp[i] - p);
 else update(dp[pre-1], dp[i]);
 }
 if (cur <= n) {
 l[0] += value[s[cur]];
 getCard(0, cur);
 }
 else {
 update(dp[n], dp[i]);
 break;
 }
 }
 }
 printf("%d\n", dp[n]);
 }
 return 0;
}

  1. #include <stdio.h>
    int main(void)
    {
    int arr[] = {10,20,30,40,50,60};
    int *p=arr;
    printf("%d,%d,",*p++,*++p);
    printf("%d,%d,%d",*p,*p++,*++p);
    return 0;
    }

    为什么是 20,20,50,40,50. 我觉得的应该是 20,20,40,40,50 . 谁能解释下?