标签:show tag integer can mission mit wan iostream sub
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3878 Accepted Submission(s): 1793
网络赛的题目还真是难理解
题意我就不说了 说下理解吧。
一开始想的时候一直在想怎么维护栈(就是那个黑屋子),然后处理的细节太多不靠谱。这里卡了好久,后来发现思考的方向出了问题
其实每一个男生在上台的时候 最极端的情况有两种 一种是前面的男孩都在小黑屋子里候着,在就是小黑屋子里一个人都没有。其他情况就是在这两种极端情况之间咯,那么这个将要上台男生的上台次序我们就可以枚举确定了, 这一步理解了,就发现是一个典型的区间dp题目了
我们定义dp[i][j]表示序列 i~j的男生上台的最小花费 具体的状态转移看代码~
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int inf=100000009;
int main()
{
int t;
cin>>t;
for(int Case=1;Case<=t;Case++)
{
int n;
cin>>n;
int a[101],sum[101];
cin>>a[1];
sum[1]=a[1];
for(int i=2;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
int dp[120][120];// 注意这里的次序大小都是相对大小 ,不是绝对大小
memset(dp,0,sizeof(dp));
for(int l=2;l<=n;l++)
{
for(int i=1;i+l-1<=n;i++)
{
int j=i+l-1;
dp[i][j]=inf;
for(int k=1;k<=l;k++)//枚举i是第几个上场的
{
int temp=i+k;//确定位置
/*
考虑第K个上场即在i+1之后的K-1个人是率先上场的,那么就出现了一个子问题 dp[i+1][temp]表示在第i个人之前上场的
对于第i个人,由于是第k个上场的,那么愤怒值便是a[i]*(k-1)
其余的人是排在第k+1个之后出场的,也就是一个子问题dp[temp][j],对于这个区间的人,由于排在第k+1个之后,所以整体愤怒值要加上k*(sum(temp-1))
*/
dp[i][j]=min(dp[i][j],dp[i+1][temp-1]+dp[temp][j]+a[i]*(k-1)+(sum[j]-sum[temp-1])*k);
}
}
}
printf("Case #%d: %d\n",Case,dp[1][n]);
}
return 0;
}
dp不能急~ 慢慢啃~
标签:show tag integer can mission mit wan iostream sub
原文地址:http://www.cnblogs.com/z1141000271/p/6803517.html