Uva--10891(动规 or 极大极小搜索)

2014-08-05 17:35:23

(看到网上有人用极大极小搜索 + 记忆化优化的解法,膜拜ing。。。http://www.cnblogs.com/staginner/archive/2011/12/02/2272014.html

思路:这道题由一道经典dp题改编(原题中每次只能取一个number),这里其实也一样,就是多一个枚举某此取多少个数字的过程。

  dp[i][j] 表示对于一个给定的区间[i , j],一次取能取到的最大值。sum[i][j]表示区间[i , j]内所有数的和。

  dp[i][j] = sum[i][j] - min(dp[i + k][j] , dp[i][j - k]) (0 <= k <= j - i)。(k == 0时表示[i , j]区间内数全取)

 1 /*************************************************************************
 2     > File Name: m.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Tue 05 Aug 2014 04:55:35 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 
16 int n;
17 int v[105];
18 int dp[105][105];
19 int sum[105];
20 
21 int main(){
22     while(scanf("%d",&n) == 1 && n){
23         sum[0] = 0;
24         for(int i = 1; i <= n; ++i){
25             scanf("%d",&v[i]);
26             sum[i] = sum[i - 1] + v[i];
27         }
28         memset(dp,0,sizeof(dp));
29         for(int i = 1; i <= n; ++i)
30             dp[i][i] = v[i];
31         for(int i = n; i >= 1; --i){
32             for(int j = i + 1; j <= n; ++j){
33                 int tmin = 1e9;
34                 for(int k = 1; k <= j - i; ++k){
35                     tmin = min(tmin,dp[i + k][j]);
36                     tmin = min(tmin,dp[i][j - k]);
37                 }
38                 dp[i][j] = sum[j] - sum[i - 1] - min(tmin,dp[i][j]);
39             }
40         }
41         printf("%d\n",2 * dp[1][n] - sum[n]);
42     }
43     return 0;
44 }

 

posted @ 2014-08-05 17:43  Naturain  阅读(133)  评论(0编辑  收藏  举报