dp-摸牌博弈

摸牌博弈

// 摸牌博弈
// 一维排列的卡牌,其上有不同的数字,两个对手A和B依次从中摸牌
// 卡牌及顺序均对两人可见
// 每次只能从最左或最右摸牌
// 最终摸到的卡牌数字之和最大者获胜
// 两个人都绝顶聪明(两人都会选择对自己有利对对手不利的牌)

#include <iostream>
#include <new>

#define N 20

using namespace std;

void solve();
void print_mat(int** mat, int len1, int len2);

int main(int argc, char** argv) {
    solve();

    return 0;
}

void solve() {
    int arr[N]{50,100,180,10,170,160,40,140,30,120,60,190,80,130,150,90,70,110,200,20};
    // mount 右上存放最优得分,左下存放选择的下标;也可分开存储
    int** mount = new int*[N];
    for (int i = 0; i < N; ++i) {
        mount[i] = new int[N]{0};
        mount[i][i] = arr[i];
    }

    for (int diff = 1; diff < N; ++diff) {
        for (int i = 0; i < N - diff; ++i) {
            int j = i + diff;
            if (mount[i][j-1] < mount[i+1][j]) {
                mount[i][j] = arr[j];
                if (mount[j-1][i] == i) {
                    if (i != j-1) {
                        mount[i][j] += mount[i+1][j-1];
                    }
                } else {
                    if (i != j-1) {
                        mount[i][j] += mount[i][j-2];
                    }
                }
                mount[j][i] = j;
            } else {
                mount[i][j] = arr[i];
                if(mount[j][i+1] == i+1) {
                    if (i+1 != j) {
                        mount[i][j] += mount[i+2][j];
                    }
                } else {
                    if (i+1 != j) {
                        mount[i][j] += mount[i+1][j-1];
                    }
                }
            }
        }
    }
    cout << "mount:\n";
    print_mat(mount, N, N);
    cout << "arr:\n";
    for (int i = 0; i < N; ++i) cout << arr[i] << " ";
    cout << "\nret:\t" << mount[0][N-1] << endl;

    for (int i = 0; i < N; ++i) {
        delete[] mount[i];
    }
    delete[] mount;
}

void print_mat(int** len, int len1, int len2) {
    for (int i = 0; i < len1; ++i) {
        for (int j = 0; j < len2; ++j) {
            cout << len[i][j] << " ";
        }
        cout << endl;
    }
}

测试:

$ g++ -o score score.cpp && ./score
mount:
50 100 230 110 400 270 440 410 470 530 530 720 840 750 990 840 1050 950 1250 1090
1 100 180 280 280 440 450 460 480 600 540 790 620 910 770 1000 840 1110 1040 1130
2 2 180 180 190 350 360 390 500 420 620 610 810 560 960 890 1030 1020 1230 1220
3 0 0 10 170 180 210 320 240 440 300 630 380 760 710 850 840 960 1040 980
4 0 0 4 170 170 330 330 370 470 510 660 700 700 650 830 800 920 1000 1120
5 5 0 0 0 160 160 200 300 340 340 530 530 480 660 630 750 700 950 900
6 0 0 6 0 0 40 140 180 180 240 370 320 500 470 590 540 700 740 720
7 0 0 7 0 0 7 140 140 170 260 360 450 480 580 610 610 680 810 880
8 8 0 8 0 0 0 0 30 120 150 310 340 440 470 470 540 580 740 600
9 0 0 9 0 0 0 0 9 120 120 310 310 440 440 450 510 560 710 800
10 10 0 10 0 0 10 0 0 0 60 190 250 320 330 410 480 520 680 540
11 11 11 11 11 11 11 11 11 11 11 190 190 270 320 420 410 490 610 690
0 12 0 12 0 0 12 0 0 0 0 0 80 130 230 220 300 330 500 350
13 0 0 13 0 0 13 0 13 13 13 0 13 130 150 280 280 370 480 570
14 14 14 0 0 0 14 0 0 0 0 0 14 14 150 150 240 240 440 440
15 15 0 15 0 0 15 0 0 0 15 0 15 0 0 90 90 200 290 360
0 16 0 0 0 0 16 0 16 16 0 0 16 0 0 0 70 110 270 130
17 17 0 17 0 0 17 0 17 17 17 0 17 0 0 17 17 110 200 310
18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 200 200
0 19 0 19 0 0 19 0 19 0 19 0 19 0 0 0 19 0 0 20
arr:
50 100 180 10 170 160 40 140 30 120 60 190 80 130 150 90 70 110 200 20
ret:	1090
posted @ 2023-08-13 16:36  keep-minding  阅读(9)  评论(0编辑  收藏  举报