标签: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