UVA 10891

来源:互联网 发布:java io分类 编辑:程序博客网 时间:2024/06/10 10:08

  题意:给定一组数,每一次选手可从左右两端任意一段选取连续的任意个数,至少选一个,甲先手,保证每次最优,则最后甲比乙得分多多少。

  思路:和两端取一个数字的做法差不多,即dp(i,j)表示对于从i到j的序列,先手可得得最大分,那么dp(i,j)=sum(i,j)-min{min{dp(i,k)}  (k=i~j-1),min{dp(k,j)  (k=i+1~j)}},注意再求最小值是因为可以把整个区间全部取走,所以记录子区间最小值的变量初始化应该为0。

#include <iostream>#include <algorithm>using namespace std;int dp[110][110],s[110]={0};int main(){int n;while(cin>>n&&n){for(int i=1;i<=n;i++) {cin>>dp[i][i];s[i]=s[i-1]+dp[i][i];}for(int l=2;l<=n;l++)for(int j,i=1;(j=i+l-1)<=n;i++){int t=0;for(int k=i;k<j;k++)t=min(t,dp[i][k]);for(int k=j;k>i;k--)t=min(t,dp[k][j]);dp[i][j]=s[j]-s[i-1]-t;}cout<<2*dp[1][n]-s[n]<<endl;}return 0;}


 

0 0