hdu4283 You Are the One

来源:互联网 发布:人工智能电影优酷 编辑:程序博客网 时间:2024/05/17 03:41

    刚开始没去深入挖掘题目的意思,因此一直在纠结题目中提到的黑屋子,其实仔细一想后,黑屋子只不过是为了改变出场顺序而已,所以重点又回到了原来给定的那个顺序上。想通这一点后,本题也就不难设计出状态了。

    dp(i,j)表是区间[i.j]中的人得到的最小不高兴度,现在来分析第i个人,在他之前可以有k个人已经走上了舞台(此即黑屋子的巧妙用处),则状态转移方程为:

dp(i,j)=min(  dp(i,j), k*d[i]+dp(i+1,i+k)+dp(i+k+1,j)+(k+1)*sum(i+k+1,j)  ).

之所以后面加了一项 (k+1)*sum(i+k+1,j),是因为在后面这一段人出场之前已经有 k+1 个人出场了,所以在计算他们的不高兴度时,出场顺序都少加了 k+1,因此要加上后面这一项。

//区间dp  dp[i][j]表示区间[i,j]的元素出栈得到的最小值 //对于区间[i,j],讨论第i个元素出栈,在它之前可以有k个元素出栈,其中0<=k<=j-i #include<iostream>using namespace std;const int INF=1<<30;int dp[101][101],a[101],s[101];int t,n;inline int min(int a,int b){return a<b?a:b;}int dfs(int i,int j){if(dp[i][j]!=-1)return dp[i][j];if(i>=j)return 0;dp[i][j]=INF;for(int k=0;k<=j-i;k++)dp[i][j]=min(dp[i][j],dfs(i+1,i+k)+dfs(i+k+1,j)+k*a[i]+(s[j]-s[i+k])*(k+1));//k*a[i]表示第i个人出栈的花费,(s[j]-s[i+k])*(k+1)表示[i+k+1,j]这一段人出栈增加的花费 return dp[i][j];}int main(){scanf("%d",&t);int Case=0;while(t--){Case++;scanf("%d",&n);s[0]=0;for(int i=1;i<=n;i++){scanf("%d",&a[i]);s[i]=a[i]+s[i-1];}for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)dp[i][j]=-1;printf("Case #%d: %d\n",Case,dfs(1,n));}system("pause");return 0;}/*251 2 3 4 552 2 3 4 5*/


原创粉丝点击