Chino的成绩(chino的公开赛T3)

题目背景

曾经幻想过未来的风景

或许有着另外一片天

小镇的远方

有着深远的回忆

也有着富有深情的诗篇

题目描述

Chino非常注重自己的成绩

Chino有 m 种方式给自己增加 rp 以增加成绩,她的每种增加 rp 的方式都有 n 个阶段,第 iii 种的第 j 个阶段增加的 rp 表示为 Aij ,表示连续进行了 j 天第 i 种增加 rp 的方式

Chino连续进行同一种方式,效果可能更好也可能更差,她想要知道在 n 天里能获得的最大 rp ,你能帮帮可爱的Chino吗?

输入输出格式

输入格式:

第一行,两个正整数 nm

接下来 m 行,第 i+1 行为 n 个整数( Ai1 - Ain )

输出格式:

一行一个数,最大的 rp

思路:

这道题一眼DP

但是n和m都不小

标准的nm^2过不了

于是我们就开始优化

我们可以开一个dp[i][j][k]数组

表示当前在i位,当前数字为j,j的长度为k

转移可以简化为两种:前面不是j的,前面是j的

分别转移即可

这样复杂度降到了n*n*m

还差不多,能过

但空间也是...所以我们要滚动数组

OK

代码:

// luogu-judger-enable-o2
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<iostream>
#include<cstdio>
#define rii register int i
#define rij register int j
#define rik register int k
//#define int long long 
using namespace std;
int x[10001][101],n,m;
long long dpa[10001][101];
long long dpb[10001][101];
long long zd,cd,wz,lzd,lcd,lwz;
inline int rd() {
    char ch = getchar(); int x = 0, f = 1;
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    } while('0' <= ch && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    } return x * f;
}
signed main()
{
//    scanf("%d%d",&n,&m);
    n=rd();
    m=rd();
    for(rii=1;i<=m;i++)
    {
        for(rij=1;j<=n;j++)
        {
            x[i][j]=rd();
//            scanf("%d",&x[i][j]);
//            qzh[i][j]+=qzh[i-1][j];
        }
    }
    for(rii=1;i<=n;i++)
    {
        cd=lcd,zd=lzd,wz=lwz;
        for(rij=1;j<=m;j++)
        {
            for(rik=1;k<=i-1;k++)
            {
                dpa[j][k+1]=dpb[j][k]+x[j][k+1];
                if(dpa[j][k+1]>=lzd)
                {
                    if(lwz!=j)
                    {
                        lcd=lzd;
                    }
                    lzd=dpa[j][k+1];
                    lwz=j;
                }
            }
            if(wz==j)
            {
                dpa[j][1]=cd+x[j][1];
            }
            else
            {
                dpa[j][1]=zd+x[j][1];
            }
            if(dpa[j][1]>=lzd)
            {
                if(lwz!=j)
                {
                    lcd=lzd;
                }
                lzd=dpa[j][1];
                lwz=j;
            }
        }
        if(i==n)
        {
            cout<<lzd;
            return 0;
        }
        for(rij=1;j<=m;j++)
        {
            for(rik=1;k<=i;k++)
            {
                dpb[j][k]=dpa[j][k];
            }
        }
    }
    
}
原文地址:https://www.cnblogs.com/ztz11/p/9516293.html