这道题的题意就是两个人可以从左边或者右边进行选取一段连续区间,然后每个人都是最优的,A先手B后手,然后问如此取完后,两人的差值是多少。
思路:由于一个人取多少石子也要看之后的影响,所以最终的大问题一定也是由小问题慢慢累积得到的。所以这种情形就考虑到可以用区间dp。在这里我的方法用的是dfs写的。
其中,我们要想办法在一段段小连续区间最优值之间找一个最小的,意思就是说,我想从右边开始取,然后我要从左边找一段连续的,然后如果这个最小值还大于0的话,那么说明我从右边取所有的,这样才会最大。如果最小值是小于0的,那么显而易见,我用这段的总和减去从左边开始取的这一段的最小值就会使我拿到的最优。这样就是一种递推的过程。
显然,初值dp[i][i]=a[i];
思路参考:
代码:
#include
using namespace std;
int vis[110][110];
int dp[110][110];
int sum[110];
int a[110];
int dfs(int begin,int end)
{
if(vis[begin][end]==1)
return dp[begin][end];
int maxx=;
vis[begin][end]=1;
for(int i=begin+1;i<=end;i++)
{
minn=min(minn,dfs(i,end));
}
for(int i=begin;i<=end-1;i++)
{
minn=min(minn,dfs(begin,i));
}
dp[begin][end]=sum[end]-sum[begin-1]-minn;
return dp[begin][end];
}
int main()
{
int n;
while(scanf("%d",&n))
{
if(n==0)
break;
sum[0]=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
int lala=dfs(1,n);
cout<