UVA 10891
来源:互联网 发布:宁波傲强自动编程软件 编辑:程序博客网 时间:2024/06/16 09:08
Root
![Problem Stats Problem Stats](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_stats.png)
![Download as PDF Download as PDF](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_pdf.png)
![Submit Submit](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_submit.png)
![Problem Stats Problem Stats](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_stats.png)
![uDebug](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_debug.png)
![Download as PDF Download as PDF](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_pdf.png)
10891 - Game of Sum
Time limit: 3.000 secondsThis is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at a time. He can take as many consecutive numbers as he wants during his time. The game ends when all numbers are taken from the array by the players. The point of each player is calculated by the summation of the numbers, which he has taken. Each player tries to achieve more points from other. If both players play optimally and player A starts the game then how much more point can player A get than player B?
Input
The input consists of a number of cases. Each case starts with a line specifying the integer n (0 <
n ≤ 100), the number of elements in the array. After that, n numbers are given for the game. Input is
terminated by a line where n = 0.
Output
For each test case, print a number, which represents the maximum difference that the first player
obtained after playing this game optimally.
Sample Input
4
4 -10 -20 7
4
1 2 3 4
0
Sample Output
7
10
题意是可以理解为有n堆石头,A跟B两个人一次从中拿石头,每人最多可连续拿k堆,也就是不限制,A先拿。问两者都在最优的情况下,A能比B多拿几个。
首先这属于博弈问题,菜鸡对博弈了解很少,区间DP还是可以。就是枚举区间i,j,然后不断取值的操作。需要先对原数组进行处理,两层for循环,外层的i从0到n-1,内层的j从i到最后,sum数组储存从i到j的和。然后进行dfs。剩下的就是区间dp+记忆化搜索了,具体实现还是看代码吧,一目了然。
代码实现:
#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<cstdio>#define ll long long#define mset(a,x) memset(a,x,sizeof(a))using namespace std;const double PI=acos(-1);const int inf=0x3f3f3f3f;const double esp=1e-6;const int maxn=250005;const int mod=1e9+7;int dir[4][2]={0,1,1,0,0,-1,-1,0};ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}ll lcm(ll a,ll b){return a/gcd(a,b)*b;}ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}int dp[105][105],map[105],visit[105][105],sum[105][105],n;int dfs(int l,int r){if(l>r)return 0;if(visit[l][r]) //如果访问,返回DP[l][r] return dp[l][r];int ans=-1e9;visit[l][r]=1; //标记 for(int k=1;k<=r-l+1;k++){ans=max(ans,sum[l][r]-min(dfs(l+k,r),dfs(l,r-k))); //ans储存每次取值能得到的最大值,用sum[l][r]减去区间内最小的值就是最大值 }dp[l][r]=ans; //记忆化 return ans;}int main(){int i,j,k;while(cin>>n&&n){mset(dp,0);mset(visit,0);for(i=0;i<n;i++)cin>>map[i];for(i=0;i<n;i++){int summ=0;for(j=i;j<n;j++){summ+=map[j];sum[i][j]=summ;}}int ans=2*dfs(0,n-1)-sum[0][n-1]; //sum数组包含dfs得到的区间和其余区间,此处要求sum中除去dfs得到的值,并计算差值 cout<<ans<<endl;}return 0;}
阅读全文
0 0
- uva 10891
- UVa 10891
- UVA 10891
- UVA 10891
- uva 10891
- UVa 10891
- uva 10891
- UVA 10891
- uva 10891 sum
- uva 10891(dp+博弈)
- UVA 10891【区间dp】
- Uva 10891 dp
- uva
- UVA
- UVA
- UVA
- uva
- UVA
- 多次fork问题(python 版)
- 2735: 杨辉三角形
- 五花八门的main()
- Codeforces Round #442 (Div. 2) A B
- 欢迎使用CSDN-markdown编辑器
- UVA 10891
- 安卓客户端和服务器端的通信(勘误填坑版)
- 封装
- Activity和fragment的封装
- 303. Range Sum Query
- 网络判断,返回设置页面
- Angularjs敏感字符
- svn提交遇到冲突解决方法
- 购物车案列