您的位置:首页 > 其它

hdu 4283 You Are the One (2012 ACM/ICPC Asia Regional Tianjin Online 1006 )

2012-09-10 14:04 405 查看
一开始的想法是贪心, 是错的。 最后是dp做的dp[x][y]表示第x位到第y位所需要的花费, 然后是转移方程 dp到x位的时候会有3个决策

1. x最先出栈;

2.x最后出栈;

3.先有i个出栈,然后x出栈,到剩下的出栈;

/*tmp = min( tmp, a[x]*i + dfs( x+1, x+i ) + dfs( x+i+1, y ) + (i+1)*(s[y]-s[x+i]) ); //
这一句中的(i+1)*(s[y] - s[x+i])是表示dp[x+i+1][y]之前有i+1个人先出栈了之后所要增加的花费


*/

#include<cstdio>
#include<cstring>
#define M 110
#define inf 1<<30
int dp[M][M], s[M], a[M];
int n;
int min( int a, int b ){ return a > b? b: a; }
int dfs( int x, int y )
{
if( dp[x][y] != -1 )
return dp[x][y];
if( x >= y )
return dp[x][y] = 0;
int tmp = dfs( x+1, y ) + s[y] - s[x]; //x位置最先出栈
for( int i = 1; i < y - x; ++i ){      //x位置前面有i个出栈
tmp = min( tmp, a[x]*i + dfs( x+1, x+i ) + dfs( x+i+1, y ) + (i+1)*(s[y]-s[x+i]) );
}
tmp = min( tmp, dfs( x+1, y ) + a[x]*(y-x) ); //x位置最后出栈
return dp[x][y] = tmp;

}
int main()
{
int t = 0, T;
scanf( "%d", &T );
while( T-- ){
scanf( "%d", &n );
s[0] = 0;
memset( dp, -1, sizeof(dp) );
for( int i = 1; i <= n; i++ ){
scanf( "%d", a + i );
s[i] = s[i-1] + a[i];
}
printf( "Case #%d: %d\n", ++t, dfs( 1, n ) );
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐