【UVA - 10891 Game of Sum 】【HRBUST - 1622】 Alice and Bob (区间dp,博弈问题)
題干:
有一個長度為N的整數序列,Alice和Bob輪流取數,Alice先取。每次玩家只能從左端或者右端
取一個或多個數,但不能兩端都取。所有數都被取走后游戲結束,然后統計每個人取走的所有數之和,
作為各自的得分。兩個人采取的策略都是讓自己的得分盡量高,并且兩個人都足夠聰明。
Input
輸入第一行為組數T(T<=10)。
對于每組數據第一行為一個整數N(1<=N<=100),第二行為給定的整數序列。
整數的絕對值<=100
Output
對于每組數據,輸出Alice和Bob都采取最優策略的情況下,Alice減去Bob的得分后的結果。
Sample Input
2
4
4 -10 -20 7
4
1 2 3 4
Sample Output
7
10
Hint
對于第一組數據: 第一步Alice從左端取1個數,第二步Bob從右端取一個數。?
第三步Alice從左端取一個數,?第四步只剩下一個數被Bob取走。
所以,Alice的得分減去Bob的得分為7。
對于第二組數據:Alice直接將全部數取走,所以Alice的得分減去Bob的得分為10。
題目大意:
? ?兩個題是一樣的題干,只是輸入格式是不同的,Uva的是EOF結束,HRBUST的是輸入樣例個數t。
解題報告:
? ??可以知道整體石子的總和一定的,所以一個人的得分越高,另一個人的得分就越低。不管怎么取任意時刻游戲的狀態都是原始序列的一段連續子序列(即被玩家取剩下的序列)。
? 這里就可以用記憶化搜索了,用dp[i][j]表示在剩下i~j區間數字,在雙方都采取最優策略的情況下,先手得分最大值。
? ? ?d[i][j] = sum[i][j] - min(dp(i + k, j), dp(i, j - k)); (1 <= k <= j - i + 1) ( sum[i][j] 表示i到j的前綴和之差)
AC代碼:
#include<bits/stdc++.h> #define ll long long using namespace std; const int INF = 0x3f3f3f3f; ll dp[205][205]; ll sum[205],a[205]; ll dfs(int l,int r) {if(dp[l][r] != -1) return dp[l][r];if(l == r) return dp[l][l]=a[l]; // ll maxx = sum[r] - sum[l-1];ll maxx = -INF;for(int i = l+1; i<=r; i++) {maxx = max(maxx , sum[r] - sum[l-1] - dfs(i,r));}for(int i = r-1; i>=l; i--) {maxx = max(maxx , sum[r] - sum[l-1] - dfs(l,i));} // printf("dp[%d][%d] = %lld\n",l,r,maxx);maxx = max(maxx,sum[r] - sum[l-1]);return dp[l][r] = maxx; } int main() {int t,n;cin>>t;while(t--) {scanf("%d",&n);memset(sum,0,sizeof sum);memset(dp,-1,sizeof dp);for(int i = 1; i<=n; i++) scanf("%lld",&a[i]),sum[i] = sum[i-1] + a[i];printf("%lld\n",2*dfs(1,n) - sum[n]);}return 0 ; }//18:04 - 18:17總結:
? ?這樣是可以AC的,或者直接用這一句
//?? ?ll maxx = sum[r] - sum[l-1];
? ? 總之,就是要把“一次全取光”這種情況也考慮進去。
總結
以上是生活随笔為你收集整理的【UVA - 10891 Game of Sum 】【HRBUST - 1622】 Alice and Bob (区间dp,博弈问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国广电放号第二天:网友已经拿到电话卡
- 下一篇: 经典三色纹辨识度拉满:iQOO 10传奇