• HDU6764 Blood Pressure Game(神级DP)


    Gugulu,一个JBer,两年前是ACMer,来到HDOJ,再次参加2020年的多大学培训比赛。然而,每次古古鲁来到区域赛,他总是得到一枚铁质奖牌,并会把这场比赛看成是JB。为了缓解痛苦,古古鲁会去上海迪士尼乐园玩过山车。古古鲁非常喜欢高血压的感觉,这让他觉得自己就像一只快乐的松鸡,忘记了所有错误的答案和超出的时间限制等等。


    我们可以把过山车的路径看作是一个具有不同高度的转折点的列表,它可以表示为一个数组{a1,a2,a3,…,an}大小为n,过山车游戏结束后Gugulu的最终血压被计算为n−1对相邻数组数之间差值的所有绝对值之和,i、 e.∑n−1i=1 | ai−ai+1 |。

    古古鲁总是获得铁牌,而且总是获得铁牌,这让他一次又一次地坐过山车。然而,随着游戏的增多,他对能使自己快乐的血压值的阈值不断提高。因此,上海迪士尼乐园的过山车已经不能满足古古鲁的需求了。

    因此,古古鲁决定重新排列{a1,a2,a3,…,an}以使他的血压尽可能高。此外,他还想知道可以达到的血压最大k值和相应的排列数。

    你,另一个JBer,确信古古鲁足够聪明,可以得到最高的血压。为了挽救古古鲁的生命,事先与合适的心脏病专家预约,计算出正确的答案是非常重要的。你必须解决这个问题!古古鲁的血压已经失控了!


    输入

    输入的第一行包含测试用例数T(1≤T≤5)。T测试用例如下。

    对于每个测试用例,第一行包含两个整数,n(2≤n≤600)和k(1≤k≤20)。

    然后,在第二行,有n个整数{a1,a2,a3,…,an}(1≤ai≤106),表示n个原始过山车转弯点。因为它是一个令人兴奋的过山车,所以可以保证数组中的所有n个整数是成对不同的。


    输出

    对于每个测试用例,输出k行。对于第i行(1≤i≤k),打印两个数字wi和ci,其中wi表示可以达到的第i个最大可能血压值,ci表示模109+7的相应排列数。请注意,当第i个最大可能值不存在时,请打印“-1”。

    题解:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=605;
    const int mod=1e9+7;
    int t;
    int n,m,k;
    int a[maxn];
    struct qnode {
        int x,y;
        qnode () {
            
        }
        qnode (int xx,int yy) {
            x=xx;
            y=yy;
        }
        bool operator < (const qnode &r) const {
            return x>r.x;
        }
    };
    struct inFo {
        int cnt;
        qnode v[maxn];
        void clr () {cnt=0;}
        void add (int A,int B) {
            v[++cnt]=qnode(A,B);
        }
        void fix () {
            sort(v+1,v+cnt+1);
            int i,j,k=0;
            for (i=1;i<=cnt;i=j) {
                int tt=0;
                for (j=i;j<=cnt&&v[i].x==v[j].x;j++) tt=(tt+v[j].y)%mod;
                v[++k]=qnode(v[i].x,tt);
                if (k>=m) break;
            }
            cnt=k;
        }
    }f[2][maxn][3];
    int main () {
        scanf("%d",&t);
        while (t--) {
            scanf("%d%d",&n,&m);
            for (int i=1;i<=n;i++) scanf("%d",a+i);
            sort(a+1,a+n+1);
            for (int i=0;i<2;i++)
                for (int j=0;j<=n;j++)
                    for (int k=0;k<3;k++)
                        f[i][j][k].clr();
            f[1][1][0].add(0,1);
            f[1][1][1].add(0,2);
            int tt=1;
            for (int i=1;i<n;i++) {
                for (int j=0;j<=n;j++)
                    for (int k=0;k<3;k++)
                        f[tt^1][j][k].clr();
                for (int j=0;j<=n;j++)
                    for (int k=0;k<3;k++) {
                        f[tt][j][k].fix();
                        int cnt=f[tt][j][k].cnt;
                        if (!cnt) continue;
                        int base=(a[i+1]-a[i])*(j*2-k);
                        for (int l=1;l<=cnt;l++) {
                            int A=base+f[tt][j][k].v[l].x;
                            int B=f[tt][j][k].v[l].y;
                            if (j+1>k)
                                f[tt^1][j+1][k].add(A,1ll*B*(j+1-k)%mod);
                            if (j>1)
                                f[tt^1][j-1][k].add(A,1ll*B*(j-1)%mod);
                            if (j*2>k)
                                f[tt^1][j][k].add(A,1ll*B*(j*2-k)%mod);
                            if (k<2) {
                                f[tt^1][j+1][k+1].add(A,1ll*B*(2-k)%mod);
                                f[tt^1][j][k+1].add(A,1ll*B*(2-k)%mod);
                            } 
                        }
                    }
                tt^=1;
            }
            f[tt][1][2].fix();
            int i;
            for (i=1;i<=f[tt][1][2].cnt&&i<=m;i++) {
                printf("%d %d
    ",f[tt][1][2].v[i].x,(f[tt][1][2].v[i].y%mod+mod)%mod);
            }
            for (;i<=m;i++) printf("-1
    ");
        }
    }
  • 相关阅读:
    关于工作中Git相关的总结
    浅谈MySQL的优化
    由内搜推送思考Kafka 的原理
    SOA和微服务架构
    Centos7.2 搭建Lamp服务器以及迁移WordPress个人博客详细过程
    MyISAM和InnoDB索引实现区别
    图解高内聚与低耦合
    图解Java常用数据结构(一)
    Java源码安全审查
    Java高并发之锁优化
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13685980.html
Copyright © 2020-2023  润新知