UVA -10891 - Game of Sum
2014-07-31 19:24
441 查看
题目链接~~>
做题感悟:感觉这题很经典,百度了一下才理解怎么做。
解题思路:
这里设 d( i , j ) 代表原序列的第 i ~ j 个元素组成的序列的子序列,在双方都采取最优策略的情况下,先手得分的最大值。那么,如果先手要获得最大值同时让后手得到最小值,因此: d( i , j ) = sum ( i , j ) - min{ d( i+1, j ) , d( i+2 , j ) …… d( j , j ) , d( i , j - 1 ) , d( i , j - 2 ) …… d(i , i ) , 0 } ,sum( i , j
) 是元素 i 到 j 的数之和,‘ 0 ’ 代表取完所有的数。
进一步的优化:d( i , j ) = sum( i , j ) - min { d( i+1 , j ) , d( i + 2 , j ) ……d( j , j ) , d( i , j - 1 ) ,d(i , j - 2 ) ……d( i , i ) , 0 } ,令 f( i, j ) = min{d( i , j ) ,d( i+1 , j ) , d(
i + 2 , j ) ……d( j , j ) }, g( i , j ) = min{ d( i , j - 1 ) , d( i , j - 1 ) , d( i , j - 2 ) …… d(i , i ) } ,则状态转移方程:d( i , j ) = sum ( i , j ) - min{ f( i+1 , j ) ,g( i, j - 1 ) , 0 } ,这里 f , g 也可以快速递推出来:f( i , j ) = min{ d( i , j ) ,f( i + 1 , j
) } , g( i , j ) =min{ d( i , j ) , g( i ,j - 1 ) } .
代码:
优化代码:
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<stdlib.h>
#define INT __int64
using namespace std ;
const int INF = 99999999 ;
const int MY = 100 + 10 ;
const int MX = (1<<11) + 5 ;
const int mod = 1000000000 + 7 ;
int n ;
int f[MY][MY],g[MY][MY],d[MY][MY],a[MY],S[MY] ;
void DP()
{
for(int i=1 ;i<=n ;i++)
f[i][i]=g[i][i]=d[i][i]=a[i] ;
for(int L=1 ;L<n ;L++)
for(int i=1 ;i+L<=n ;i++)
{
int j = i+L ;
int m = 0 ;
m = min(m , f[i+1][j]) ;
m = min(m , g[i][j-1]) ;
d[i][j]=S[j] - S[i-1] - m ;
f[i][j]=min(d[i][j],f[i+1][j]) ;
g[i][j]=min(d[i][j],g[i][j-1]) ;
}
cout<<2*d[1]
-S
<<endl ;
}
int main()
{
while(scanf("%d",&n),n)
{
S[0]=0 ;
for(int i=1 ;i<=n ;i++)
{
scanf("%d",&a[i]) ;
S[i]=S[i-1]+a[i] ;
}
DP() ;
}
return 0 ;
}
做题感悟:感觉这题很经典,百度了一下才理解怎么做。
解题思路:
这里设 d( i , j ) 代表原序列的第 i ~ j 个元素组成的序列的子序列,在双方都采取最优策略的情况下,先手得分的最大值。那么,如果先手要获得最大值同时让后手得到最小值,因此: d( i , j ) = sum ( i , j ) - min{ d( i+1, j ) , d( i+2 , j ) …… d( j , j ) , d( i , j - 1 ) , d( i , j - 2 ) …… d(i , i ) , 0 } ,sum( i , j
) 是元素 i 到 j 的数之和,‘ 0 ’ 代表取完所有的数。
进一步的优化:d( i , j ) = sum( i , j ) - min { d( i+1 , j ) , d( i + 2 , j ) ……d( j , j ) , d( i , j - 1 ) ,d(i , j - 2 ) ……d( i , i ) , 0 } ,令 f( i, j ) = min{d( i , j ) ,d( i+1 , j ) , d(
i + 2 , j ) ……d( j , j ) }, g( i , j ) = min{ d( i , j - 1 ) , d( i , j - 1 ) , d( i , j - 2 ) …… d(i , i ) } ,则状态转移方程:d( i , j ) = sum ( i , j ) - min{ f( i+1 , j ) ,g( i, j - 1 ) , 0 } ,这里 f , g 也可以快速递推出来:f( i , j ) = min{ d( i , j ) ,f( i + 1 , j
) } , g( i , j ) =min{ d( i , j ) , g( i ,j - 1 ) } .
代码:
#include<stdio.h> #include<cmath> #include<string.h> #include<iostream> #include<iomanip> #include<algorithm> #include<stdlib.h> #define INT long long int using namespace std ; const int INF = 99999999 ; const int MY = 20 + 10 ; const int MX = 100 + 10 ; int n ; int dp[MX][MX],sum[MX] ; int DP(int x,int y) { if(dp[x][y]!=-1) return dp[x][y] ; int& ans = dp[x][y] ; ans=0 ; for(int i=x+1 ;i<=y ;i++) ans = min(ans,DP(i,y)) ; for(int i=x ;i<y ;i++) ans = min(ans,DP(x,i)) ; ans = sum[y]-sum[x-1]-ans ; return ans ; } int main() { int x ; while(scanf("%d",&n),n) { sum[0]=0 ; for(int i=1 ;i<=n ;i++) { scanf("%d",&x) ; sum[i]=sum[i-1]+x ; } memset(dp,-1,sizeof(dp)) ; cout<<2*DP(1,n)-sum <<endl ; } return 0 ; }
优化代码:
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<stdlib.h>
#define INT __int64
using namespace std ;
const int INF = 99999999 ;
const int MY = 100 + 10 ;
const int MX = (1<<11) + 5 ;
const int mod = 1000000000 + 7 ;
int n ;
int f[MY][MY],g[MY][MY],d[MY][MY],a[MY],S[MY] ;
void DP()
{
for(int i=1 ;i<=n ;i++)
f[i][i]=g[i][i]=d[i][i]=a[i] ;
for(int L=1 ;L<n ;L++)
for(int i=1 ;i+L<=n ;i++)
{
int j = i+L ;
int m = 0 ;
m = min(m , f[i+1][j]) ;
m = min(m , g[i][j-1]) ;
d[i][j]=S[j] - S[i-1] - m ;
f[i][j]=min(d[i][j],f[i+1][j]) ;
g[i][j]=min(d[i][j],g[i][j-1]) ;
}
cout<<2*d[1]
-S
<<endl ;
}
int main()
{
while(scanf("%d",&n),n)
{
S[0]=0 ;
for(int i=1 ;i<=n ;i++)
{
scanf("%d",&a[i]) ;
S[i]=S[i-1]+a[i] ;
}
DP() ;
}
return 0 ;
}
相关文章推荐
- UVA 10891 Game of Sum(经典区间dp)
- uva 10891 Game of Sum(区间dp)
- UVA - 10891 Game of Sum
- uva 10891 - Game of Sum
- UVA 10891 Game of Sum(区间DP)
- UVa 10891 Game of Sum / 记忆化搜索
- Uva-10891-Game of Sum
- UVA 10891 Game of Sum (动态规划)
- UVa 10891 - Game of Sum
- UVA 10891 Game of Sum (决策优化)
- UVA 10891 Game of Sum(记忆化搜索+博弈)
- UVA - 10891 Game of Sum (区间DP)@
- UVa10891 Game of Sum
- Uva 10891 Game of Sum(区间博弈dp)
- UVA 10891 Game of Sum
- UVA 10891 Game of Sum(区间DP)
- uva10891 Game of Sum
- UVa 10891 - Game of Sum
- Uva-10891-Game of Sum
- uva 10891 - Game of Sum