POJ 3186 简单dp 类田忌赛马

要求:一个盒子内有顺序排列n个正整数,这n个正整数可以从盒子的左口出去也可以从右口出去,靠近端口的出去后远离端口的才可以出去。一天出去一个正整数,若第k天出去的数为x,则这一天获得价值为k*x。求n天可获得的最大价值。

方法:简单dp 类田忌赛马

1.dp[i][j]表示前i天从左口出去了j个正整数。

2.状态转移方程:dp[i][j] = max(dp[i-1][j-1] + i * a[j] , dp[i - 1][j] + i * a[n - i + j + 1]) 。

3.注意j可以是0,边界条件需注意。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<map>
#define inf 0x3f3f3f3f
using namespace std ;
int n ;
int a[2005] ;
long long dp[2005][2005] ; 
long long ans = -1 ;
int main()
{
  int i , j ;
  scanf("%d" , &n) ;
  for(i = 1 ; i <= n ; i ++)
    scanf("%d" , &a[i]) ;
  memset(dp , 0 , sizeof(dp)) ;
  for(i = 1 ; i <= n ; i ++)
  {
    for(j = 0 ; j <= i ; j ++)
	{             
	  if(j == 0)
	     dp[i][j] =  dp[i - 1][j] + i * a[n - i + j + 1] ;  
	  else	                 
	     dp[i][j] = max(dp[i-1][j-1] + i * a[j] , dp[i - 1][j] + i * a[n - i + j + 1]) ;	
	}	
  }
  for(i = 0 ; i <= n ; i ++)
    ans = max(ans , dp[n][i]) ;	
  printf("%lld\n" , ans) ;
} 

猜你喜欢

转载自blog.csdn.net/Irving0323/article/details/85253994