1. 程式人生 > >博弈論的一些理解

博弈論的一些理解

opened 選擇 發生 for AS 強行 tor aps fine

博弈論的一些理解

一、起因

  之前在某個可怕的比賽中看到了博弈論的簽到題,但是由於三個人沒有一個學過博弈論以至於強行放棄的事故發生。我決定立刻,馬上開坑博弈論專題。

二、分類以及相關題目

  1. 動態博弈
      POJ1678
      UVA3668

  2. 巴士博弈

三、題解

  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; }
POJ1678

博弈論的一些理解