Uva 10891 Game of Sum - 区间DP..记忆化搜索

      题意:

               有一列数...A,B分别来取..每次只能从两头中一头开始拿走若干个..问最后A拿走的数比B拿走的大多少...

      题解:

               首先能想到是区间DP的问题...对于一个区间..感觉上是可以通过其子区间推出最优解的..

               dp [ i ] [ j ] 代表在i,j区间能取得的最大值...

               那么有 dp [ i ] [ j ] = sum [ i ] [ j ] - min ( dp [ i ] [ k ] , dp [ k ]  [ j ] ) , ( i<=k<=j ) 

               最后得出dp[ 1 ] [ n ] 代表了A能拿的最大价值.那么题目所需要的答案为 ans = dp[ 1 ] [n ] - ( sum [ 1 ] [ n ] - dp [ 1 ] [ n ] )

      总结

               所有的DP问题都可以用两种大方向来写: 1、递推  2、记忆化搜索

               记忆化搜索的好处是十分直观....特别是对于树形DP和区间DP这类型的问题.


Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<algorithm>
#define ll long long
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 105
using namespace std;     
int n,sum[MAXN],dp[MAXN][MAXN];
bool used[MAXN][MAXN];
void dfs(int s,int e)  
{ 
      if (s>e) return;
      if (used[s][e]) return;  
      used[s][e]=true;
      dp[s][e]=-oo;
      int S=sum[e]-sum[s-1];  
      for(int k=1;k<=e-s+1;k++)
      {  
             dfs(s+k,e),dfs(s,e-k);
             dp[s][e]=max(dp[s][e],S-min(dp[s+k][e],dp[s][e-k]));  
      }  
      return;  
}  
int main()
{          
       while (~scanf("%d",&n) && n)
       {
              int i,x; 
              sum[0]=0;
              for (i=1;i<=n;i++) 
              {
                    scanf("%d",&x); 
                    sum[i]=sum[i-1]+x;
                    dp[i][i]=x;
              }
              memset(used,false,sizeof(used));
              dfs(1,n);   
              printf("%d\n",dp[1][n]-(sum[n]-dp[1][n]));
       }
       return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值