Deck of Cards ZOJ

题意:一个特殊21点游戏 具体http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2852

题解:建一个三维dp,表示三个卡槽分别为i,j,l分时最大的收益情况。

    对所有当前状态dp,将下一个可能的状态存入f,

坑:~-1==0

#define _CRT_SECURE_NO_WARNINGS
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<string>
#include<stack>
#include<ctime>
#include<list>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<sstream>
#include<fstream>
#include<iostream>
#include<functional>
#include<algorithm>
#include<memory.h>
//#define INF 0x3f3f3f3f
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
#define rep(i,t,n)  for(int i =(t);i<=(n);++i)
#define per(i,n,t)  for(int i =(n);i>=(t);--i)
#define mp make_pair
#define pb push_back
#define mmm(a,b) memset(a,b,sizeof(a))
//std::ios::sync_with_stdio(false);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void smain();
#define ONLINE_JUDGE
int main() {
    //ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    FILE *myfile;
    myfile =freopen("C:\Users\SuuTT\Desktop\test\in.txt", "r", stdin);
    if (myfile == NULL)
        fprintf(stdout, "error on input freopen
");
    /*FILE *outfile;
    outfile= freopen("C:\Users\SuuTT\Desktop\test\out.txt", "w", stdout);
    if (outfile == NULL)
        fprintf(stdout, "error on output freopen
");*/
    long _begin_time = clock();
#endif
    smain();
#ifndef ONLINE_JUDGE
    long _end_time = clock();
    printf("time = %ld ms.", _end_time - _begin_time);
#endif
    return 0;
}
int dir[4][2] = { 1,0,0,1,-1,0,0,-1 };
const int maxn = 2e2 + 5;
int f[22][22][22], dp[22][22][22];

int n; int ans;
int num(char c) {
    if (c >= '0'&&c <= '9')return c - '0';
    else if (c == 'A')return 1;
    else if (c == 'F')return -1;
    else return 10;
}

void smain() {
    while (cin >> n) {
        if (n == 0)break;
        mmm(f, 0); mmm(dp, 0);
        string c;
        cin >> c;
        int x = num(c[0]);
        if (x==-1) {
            //cout << ~x << endl;
            dp[0][0][0] = 350;
            ans = 350;
        }
        else {
            dp[x][0][0] = 50;
            dp[0][x][0] = 50;
            dp[0][0][x] = 50;
            ans = 50;
        }
        rep(i, 2, n) {
            string c;
            cin >> c;
            int x = num(c[0]);
            rep(j, 0, 21)rep(k, 0, 21)rep(l, 0, 21) if(dp[j][k][l]){
                int t = dp[j][k][l];
                if ((x == -1 && j < 21) || x + j == 21) f[0][k][l] = max(f[0][k][l], t + 150);//放第一组//正好21,[j][k][l]->[0][k][l]
                else if (x + j < 21)f[j + x][k][l] = max(f[x + j][k][l], t + 50);//没到21[j][k][l]->[x + j][k][l]
                else if (x + j > 21 && j < 21)f[21][k][l] = max(f[21][k][l], t + 50);//超了21[j][k][l]->[21][k][l]
                
                if ((x == -1 && k < 21) || x + k == 21) { f[j][0][l] = max(f[j][0][l], t + 250); }
                else if (x + k < 21)f[j][k+x][l] = max(f[j][k+x][l], t + 50);
                else if (x + k > 21 && k < 21)f[j][21][l] = max(f[j][21][l], t + 50);

                if ((x == -1 && l < 21) || x + l == 21) { f[j][k][0] = max(f[j][k][0], t + 350); }
                else if (x + l < 21)f[j][k][l+x] = max(f[j][k][l+x], t + 50);
                else if (x + l > 21 && l < 21)f[j][k][21] = max(f[j][k][21], t + 50);
            }
            rep(j, 0, 21)rep(k, 0, 21)rep(l, 0, 21)dp[j][k][l] = f[j][k][l], ans = max(ans,dp[j][k][l]), f[j][k][l] = 0;
        }
        cout << ans << endl;
    }
    
}
成功的路并不拥挤,因为大部分人都在颓(笑)
原文地址:https://www.cnblogs.com/SuuT/p/9013100.html