博弈论的一些理解
Posted 六花的邪王真眼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了博弈论的一些理解相关的知识,希望对你有一定的参考价值。
博弈论的一些理解
一、起因
之前在某个可怕的比赛中看到了博弈论的签到题,但是由于三个人没有一个学过博弈论以至于强行放弃的事故发生。我决定立刻,马上开坑博弈论专题。
二、分类以及相关题目
-
动态博弈
POJ1678
UVA3668 -
巴士博弈
三、题解
1、POJ1678
首先分析题目,可以发现,a,b的具体大小大于0,则这意味着每次选取的时候后一个数必然大与前一个数字。因此具有单调性,可以先将数组排序。(按照这个道理其实可以去除掉所有小于a的数字)
其次,首先假设dp[i]代表当先手面临arr[i]时的最优选择,则,应当认为,每次状态转移的目的实际上是在替后手做决策——在当前状态选取最小收益的点作为后续选择。
最后考虑特殊点——游戏结束点,dp[i]应当为arr[i]本身。
#include<iostream> #include<stdlib.h> #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #include<vector> #include<set> #include<map> #include<queue> using namespace std; #define ll long long const ll MAXN=100233; const ll INF = (ll)1<<40; ll arr[MAXN]; ll dp[MAXN]; ll n,a,b; void init() { cin>>n>>a>>b; for(int i=0;i<n;++i) cin>>arr[i]; sort(arr,arr+n); for(int i= n-1;i>=0;--i) { dp[i] = INF; for(int j=i+1;j<n;++j) { if(arr[j]<arr[i]+a)continue; if(arr[j]>arr[i]+b)break; dp[i] = min(arr[i] - dp[j],dp[i]); } if(dp[i] == INF)dp[i] = arr[i]; } ll ans = -INF; for(int i=0;i<n;++i) { if(arr[i] < a)continue; if(arr[i] > b)break; ans = max(dp[i],ans); } if(ans == -INF)ans = 0; cout<<ans<<"\n"; } int main() { int t; cin>>t; while(t--) init(); return 0; }
以上是关于博弈论的一些理解的主要内容,如果未能解决你的问题,请参考以下文章