首页 > 其他分享 >dp-摸牌博弈

dp-摸牌博弈

时间:2023-08-13 16:46:23浏览次数:45  
标签:11 博弈 17 摸牌 int 18 mount 440 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

标签:11,博弈,17,摸牌,int,18,mount,440,dp
From: https://www.cnblogs.com/minding/p/17626758.html

相关文章

  • dp-最长回文子序列
    最长回文子序列算法导论3rd-15.2问题描述回文:palindrome,是正序和逆序完全相同的非空字符串一个字符串有许多子序列,可以通过删除某些字符而变成回文字符串,字符串“cabbeaf”,删掉‘c’、'e'、‘f’后剩下的子串“abba”就是回文字符串,也是其中最长的回文子序列。在一个给定的......
  • dp-最长公共子序列
    最长公共子序列目录最长公共子序列问题描述最长公共子序列不等于最长公共子串问题分析程序问题描述最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题。一个数列,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的......
  • dp-最优二叉搜索树
    最优二叉搜索树目录最优二叉搜索树问题描述问题分析思路程序问题描述最优二叉搜索树(OptimalBinarySearchTree,OptimalBST)问题,形式化定义:给定一个n个不同关键字的已排序的序列K=<k1,k2,...,kn>(k1<k2<...<kn),用这些关键字构造一棵二叉搜索树——对每个关键字ki,都有一个概......
  • 无涯教程-Perl - readpipe函数
    描述该函数将EXPR作为命令执行。然后,将输出作为标量文本中的多行字符串返回,或者将行作为列表context中的单个元素返回。语法以下是此函数的简单语法-readpipeEXPR返回值此函数在标量context中返回String,在列表context中返回List。例以下是显示其基本用法的示例代码......
  • 斜率优化DP
    前置芝士单调队列优化DP⌈写不动数据结构呜呜呜,先来补这个⌋对于一个DP,我们想优化祂的⌈转移⌋有些题目的可选状态有以下特征需要寻找最值可选状态区间平移存在可以永久去除的多余状态感性的讲,可行性是一个滑动窗口,状态两两之间都可以⌈直接比较出优劣......
  • UDP
    UDP不像TCP创建连接时有3次握手,而是直接发送数据,不管对方是否接收到。UDP网络通信不区分客户端和服务端。 UDP收发数据的步骤1.创建UDP套接字对象2.直接发送数据3.读取数据4.关闭套接字 示例服务端1'''2UDP应该说没有服务端和客户端,只是习惯称发......
  • [MDP.Net] 平台架構
    MDP.Net將應用系統切割為:模組、隔離、平台三個分層,透過架構設計提供模組重用、參數調整、環境建置...等等面向的快速開發能力。-模組:企業的商業知識、共用的功能邏輯,在MDP.Net裡會被開發成為一個一個的「模組」,方便開發人員依照商業需求,快速組合出應用系統。-隔離:MDP.Net加......
  • [MDP.Net] 模組架構
    MDP.Net遵循三層式架構,將模組開發切割為:系統展示、領域邏輯、資料存取三個分層,減少模組對於元件、平台、框架的直接依賴,提高模組自身的內聚力。-系統展示(Presentation):與目標客戶互動、與遠端系統通訊...等等的功能邏輯,會被歸類在系統展示。例如,使用MessageBox通知使用者處理......
  • DP1
    DP1P2523[HAOI2011]Problemc从后往前考虑,容易判掉无解。启发我们计数也从后往前考虑,设\(f[i][j]\)表示考虑到\([i,n]\)的位置,确定了\(j\)个人的编号的方案数。转移枚举之前确定了多少个人、在当前位置确定多少个人即可。CF311BCatsTransport求出正好接到每只小......
  • SharedPreferences
    SharedPreferences简介在Android开发过程中,有时候我们需要保存一些简单的软件配置等简单数据的信息,而如果我们直接用数据库存储的话又不太方便,在这里我们就可以用到SharedPreferences,SharedPreferences保存的数据主要是类似于配置信息格式的数据,因此保存的数据主要是简单类型的......