TYVJ 1062 合并傻子

来源:互联网 发布:网络著名作家有哪些 编辑:程序博客网 时间:2024/04/30 21:50

问题 K: TYVJ 1062 合并傻子

时间限制: 0 Sec  内存限制: 128 MB
提交: 58  解决: 20
[提交][状态][社区]

题目描述

在一个园形操场的四周站着N个傻子,现要将傻子有次序地合并成一堆.规定每次只能选相邻的2个傻子合并成新的一个傻子,并将新的一个傻子的RP数,记为该次合并的RP数。 (合并方法与NOI1999石子合并(本题库的沙子合并)相同,请大家参考上题合并方法) 将N个傻子合并成1个的最小RP数为RPn和最大RP数为RPx. 钟某人要合并他们,钟某人现在的RP为m,但是他要小心.... if  m> RPx  then  钟某人能很轻松的合并他们,并说出  ‘It  is  easy’ else  if  m< RPn  钟某人很担心,因为他必然由此变成一个沙茶,这时他要说:‘I  am..Sha...X’(以便提升RP) else      钟某人仍然担心自己可能成为一个沙茶,所以他要金蝉脱壳说:‘I  will  go  to  play  WarIII’

输入

数据的第1行试正整数n和m(1≤N≤100,m在longint范围之内)表示有N个傻子.第2行有N个数,分别表示合并每个傻子的所掉的RP数

输出/

输出文件仅一行包含一个句子表示钟某人说的话。

样例输入

4 -99994 4 5 9

样例输出

I am..Sha...X

提示

傻子+傻子=?

[提交][状态][社区]
一道动态规划题,是TYVJ 1055 沙子合并这题的变形。沙子合并详细见http://blog.csdn.net/asdfghjkl1993/article/details/19010369

这道题相当于就是用沙子合并这题的方法分别求两种情况,先算最大代价,如果小于m
则打出It is easy,如果最小代价大于m则打出I am..Sha...X,否则则打出I will go to play WarIII。

最小代价的动态方程f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1])

最大代价的动态方程f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1])
其中f[i][j]表示从i到j这个闭区间的最优解,预处理s[i]表示1到i区间内的所有沙堆之和,则s[j]-s[i-1]表示从i到j合并的代价,区间慢慢的由小变大。


#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<cmath>#include<cstdio>#include<map>#include<vector>#include<stack>#include<set>using namespace std;const int MAX=1010;const int INF=1000000000;int f[MAX][MAX];int n,m;int s[MAX];int a[MAX];void dp1(){    memset(f,0,sizeof(f));for(int i=1;i<=n-1;i++)        f[i][i+1]=a[i]+a[i+1];    for(int p=2;p<=n-1;p++)        for(int i=1;i<=n-p;i++)        {            int j=i+p;            f[i][j]=-INF;            for(int k=i;k<=j-1;k++)                f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);        }}void dp2(){    memset(f,0,sizeof(f));for(int i=1;i<=n-1;i++)        f[i][i+1]=a[i]+a[i+1];    for(int p=2;p<=n-1;p++)        for(int i=1;i<=n-p;i++)        {            int j=i+p;            f[i][j]=INF;            for(int k=i;k<=j-1;k++)                f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);        }}int main(){    while(cin>>n>>m)    {        memset(s,0,sizeof(s));        for(int i=1;i<=n;i++)        {            cin>>a[i];            s[i]=s[i-1]+a[i];//预处理        }dp1();//最大代价DPif(f[1][n]<m){printf("It is easy\n");continue;}dp2();//最小代价DPif (f[1][n]>m) printf("I am..Sha...X\n");else printf("I will go to play WarIII\n");    }    return 0;}



0 0