【Luogu】P2331最大子矩阵(DP)

  题目链接

  这题的状态转移方程真是粗鄙。

  f[i][j][k]表示前i行用了j个矩阵状态为k的时候的最大值。

  k=0:两列都不选。

  k=1:取左弃右。

  k=2:选右弃左。

  k=3:左右都选,但分属于两个独立矩阵。

  k=4:左右都选,且同属于一个矩阵。

  参考题解:孤寂的时代

  代码

#include<cstdio>
#include<cctype>
#include<cstring>

inline long long max(long long x,long long y){    return x>y?x:y;    }

inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch==‘-‘)    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-‘0‘;
        ch=getchar();
    }
    return num*f;
}

int f[103][12][6];
int que[1000][5];

int main(){
    int n=read(),m=read(),q=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)    que[i][j]=read();
    memset(f,0xaf,sizeof(f));
    for(int i=0;i<=n;++i)
        for(int j=0;j<=q;++j)    f[i][j][0]=0;
    for(int i=1;i<=n;++i){
        int a=que[i][1],b=que[i][2];
        for(int j=1;j<=q;++j){
            f[i][j][0]=max(max(f[i-1][j][0],f[i-1][j][1]),max(f[i-1][j][2],max(f[i-1][j][3],f[i-1][j][4])));
            f[i][j][1]=max(max(max(f[i-1][j-1][0],f[i-1][j][1]),max(f[i-1][j-1][2],f[i-1][j][3]))+a,f[i-1][j-1][4]+a);
            f[i][j][2]=max(max(max(f[i-1][j-1][0],f[i-1][j-1][1]),max(f[i-1][j][2],f[i-1][j][3]))+b,f[i-1][j-1][4]+b);
            f[i][j][3]=max(f[i-1][j-1][1],max(f[i-1][j-1][2],f[i-1][j][3]))+a+b;
            if(j>1)    f[i][j][3]=max(f[i][j][3],f[i-1][j-2][4]+a+b);
            f[i][j][4]=max( max(f[i-1][j-1][0],f[i-1][j-1][1]),max(f[i-1][j-1][2],f[i-1][j-1][3]))+a+b;
            f[i][j][4]=max(f[i][j][4],f[i-1][j][4]+a+b);
        }
    }
    int ans=f[n][q][1];
    if(ans<f[n][q][0])    ans=f[n][q][0];
    if(ans<f[n][q][2])    ans=f[n][q][2];
    if(ans<f[n][q][3])    ans=f[n][q][3];
    if(ans<f[n][q][4])    ans=f[n][q][4];
    printf("%d",ans);
    return 0;
}
时间: 2024-10-08 17:54:37

【Luogu】P2331最大子矩阵(DP)的相关文章

URAL_1146/uva_108 最大子矩阵 DP 降维

题意很简单,给定一个N*N的大矩阵,求其中数值和最大的子矩阵. 一开始找不到怎么DP,没有最优子结构啊,后来聪哥给了我思路,化成一维,变成最大连续和即可.为了转化成一维,必须枚举子矩阵的宽度,通过预处理的suffix可以很快计算出每一列某一段的和,然后进行一维DP即可..总复杂度为 O(N^3); #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> usi

【Luogu】P2258子矩阵(状态压缩,DP)

233今天蒟蒻我连文化课都没听光想着这个了 然后我调了一下午终于过了!!! 一看数据范围似乎是状压,然而216等于65536.开一个65536*65536的二维数组似乎不太现实. 所以Rqy在四月还是几月给我们讲这道题的时候说要半DFS半DP,时间复杂度O(2n*n3) 怎么个半DFS半DP法呢? 其实我没DFS.所以这个问题不重要. 我真的没用DFS.枚举从1到2n-1的所有集合,把二进制数中1的个数不等于r的都筛掉.然后对于每个状态,预处理出每一列内部的代价,预处理出列与列之间的代价,然后进

BZOJ 1057: [ZJOI2007]棋盘制作 悬线法求最大子矩阵+dp

1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳.而我们的主人公小Q,正是国际象棋的狂热爱好者.作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则.小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一.小Q想在这种纸中裁减

ZOJ1074 (最大和子矩阵 DP)

F - 最大子矩阵和 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the

BZOJ 1084: [SCOI2005]最大子矩阵( dp )

最多只有2列..分开来dp 1列 dp(x, k) = max( dp(x - 1, k), dp(p, k - 1) + sum(p+1~x) ) 2列 dp(a, b, k) = max( dp(a - 1, b, k), dp(a, b - 1, k), dp(p, b, k - 1) + sum1(p+1~a), dp(a, p, k - 1) + sum2(p+1~b) ) 当a = b, dp(a, b, k)还可以用dp(p, p, k - 1) + SUM(p+1~a) (0 ≤

Luogu P1057 传球游戏(dp 递推)

P1057 传球游戏 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时,拿着球没有传出去的那个同学就是败者,要给大家表演一个节目. 聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了m次以后,又回到小蛮手里.两种传球方法被视

luogu 1437 敲砖块(DP)

这道题的DP的状态设计的很有想法啊. 假如我们一行一行来选择的话,状态将会极其复杂. 如果一列一列来看的话,比如你想选aij,那么第i列的前j个都要选,并且第i+1列的前j-1个都要选. 于是状态就很好设计了,定义dp[n][i][j]表示还剩下n个要选的砖块,当前选择第i列的前j个所能达到的最大分值. 那么dp[n][i][j]=max(dp[n-j][i+1][k]+sum[i][j])(j-1<=k<=n-i). 记忆化搜索一下就OK了. # include <cstdio>

有线电视网(luogu 1273)树形DP

题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播的总费用等于传输信号的费用总和. 现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪些用户提供信号而不给哪些用户提供信号. 写一个程序找出一个方案使得有线电视网在不亏本的情况下使观看转播的用户尽可能多. 输入输出格式 输

小A点菜(luogu 1164)简单DP

题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家--餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:"随便点". 题目描述 不过uim由于买了一些辅(e)辅(ro)书,口袋里只剩 MM 元 (M \le 10000)(M≤10000) . 餐馆虽低端,但是菜品种类不少,有 NN 种 (N \le 100)(N≤100) ,第 ii 种卖 a_iai? 元 (a_i \le 1000)(ai?≤1000) .由于是很低端的餐馆,所以每种菜只