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

来源:互联网 发布:单片机基础知识 编辑:程序博客网 时间:2024/06/16 10:32

一开始的想法是贪心, 是错的。 最后是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<<30int 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 ) );}}

原创粉丝点击