P3974 [TJOI2015]组合数学
题目描述
为了提高智商,ZJY开始学习组合数学。某一天她解决了这样一个问题:给一个网格图,其中某些格子有财宝。每次从左上角出发,只能往右或下走。问至少要走几次才可能把财宝全捡完。
但是她还不知足,想到了这个问题的一个变形:假设每个格子中有好多块财宝,而每一次经过一个格子至多只能捡走一块财宝,其他条件不变,至少要走几次才可能把财宝全捡完?
这次她不会做了,你能帮帮她吗?
输入输出格式
输入格式:
第一行为一个正整数t,表示数据组数
每组数据的第一行是两个正整数n和m,表示这个网格图有n行m列。
接下来n行,每行m个非负整数,表示这个格子中的财宝数量(0表示没有财宝)。
输出格式:
对于每组数据,输出一个整数,表示至少走的次数。
输入输出样例
1
3 3
0 1 5
5 0 0
1 0 0
10
说明
数据范围
对于30%的数据,n≤5.m≤5,每个格子中的财宝数不超过5块。
对于50%的数据,n≤100,m≤100,每个格子中的财宝数不超过1000块
对于100%的数据,n≤1000,m≤1000,每个格子中的财宝不超过10^6块
解析:
这是天津市2015年的省选题(天津好像离北京很近~~~)于是乎我就做了这道题。。。
题目的意思就是用最少的链覆盖住整个图,自然而然(看过题解后)就想到了最小链覆盖;
而根据著名的(反正我是没听过)的Dilworth定理,DAG最小链覆盖的条数就等于最大点独立集/最长反链的元素个数;;;
所谓de反链就是去找一些点,其中找两个点,使其直接间接均不可达;而反链中元素最多的就是最长反链了。
所以这个题的本质上是去找这个图的最长反链。
接下来就到了我们有趣的dynamic programming环节辣;;;
由题目可知,只能从左往右,从上往下走,所以这个题的反链一定是由右上到左下的。
而从上面和右面均能形成链,所以直接它直接就可能是这个点的最长反链;
从右上走到左下是不可能的,所以我们要把右上的点加上这个点的值才可能是最长反链;
而我们要求的是最长反链,但这几个部分显然是不能够同时取的,所以要选这三个的最大值
状态转移方程就很容易写出了:
f[i][j]=max(f[i-][j+]+a[i][j],max(f[i-][j],f[i][j+]));
这里还要注意的一点就是循环变量,i是从1-〉n递增的,j是从m-〉1递减的,原因很简单,就是要满足最长反链从左下不可能到达右上的性质;
下面上代码:
#include<iostream>
#include<cstdio>//getchar要引cstdio
using namespace std;
int t,n,m;
long long a[][],f[][];//要开大!洛谷上本题有5个极限数据,不开就会RE得很惨~
int read()//读入优化
{
int f=,x=;
char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
int main()
{
t=read();
for(int s=;s<=t;s++)
{
n=read();
m=read();
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
a[i][j]=read();
f[i][j]=;
}
}
//dp
for(int i=;i<=n;i++)
{
for(int j=m;j>=;j--)
{
f[i][j]=max(f[i-][j+]+a[i][j],max(f[i-][j],f[i][j+]));
}
}
cout<<f[n][]<<endl;//千万不要忘记输出回车。。。我爆了5次零。。。
}
}
P3974 [TJOI2015]组合数学的更多相关文章
- 3997: [TJOI2015]组合数学
3997: [TJOI2015]组合数学 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 247 Solved: 174[Submit][Status ...
- BZOJ3997: [TJOI2015]组合数学(网络流)
3997: [TJOI2015]组合数学 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 405 Solved: 284[Submit][Status ...
- BZOJ 3997: [TJOI2015]组合数学 [偏序关系 DP]
3997: [TJOI2015]组合数学 题意:\(n*m:\ n \le 1000\)网格图,每个格子有权值.每次从左上角出发,只能向下或右走.经过一个格子权值-1.至少从左上角出发几次所有权值为0 ...
- 【BZOJ3997】[TJOI2015]组合数学(动态规划)
[BZOJ3997][TJOI2015]组合数学(动态规划) 题面 BZOJ 洛谷 题解 相当妙的一道题目.不看题解我只会暴力网络流 先考虑要求的是一个什么东西,我们把每个点按照\(a[i][j]\) ...
- 【BZOJ 3997】 3997: [TJOI2015]组合数学 (DP| 最小链覆盖=最大点独立集)
3997: [TJOI2015]组合数学 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 919 Solved: 664 Description 给出 ...
- 【BZOJ3997】[TJOI2015]组合数学 最长反链
[BZOJ3997][TJOI2015]组合数学 Description 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格 ...
- [TJOI2015]组合数学
题目描述 为了提高智商,ZJY开始学习组合数学.某一天她解决了这样一个问题:给一个网格图,其中某些格子有财宝.每次从左上角出发,只能往右或下走.问至少要走几次才可能把财宝全捡完. 但是她还不知足,想到 ...
- bzoj3997[TJOI2015]组合数学(求最长反链的dp)
组合数学 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走 ...
- 【BZOJ】3997: [TJOI2015]组合数学
题意 \(N \times M\)的网格,一开始在\((1, 1)\)每次可以向下和向右走,每经过一个有数字的点最多能将数字减1,最终走到\((N, M)\).问至少要走多少次才能将数字全部变为\(0 ...
随机推荐
- jq冲刺
1.入口函数$(document).ready(function(){ })简便写法:$(()=>{ }) js的入口函数window.onload()区别js的入口函数要比jq的要晚很多,wi ...
- react_app 项目开发 (2)_axios_pubsub-js
生产环境打包并运行 yarn run build 会src代码进行打包处理,在内存中生成打包文件 将打包文件保存至内存 yarn global add serve serve -s build 将 b ...
- [LeetCode] Soup Servings 供应汤
There are two types of soup: type A and type B. Initially we have N ml of each type of soup. There a ...
- php 识别二维码(转载)
近段需要写一个通过PHP来识别二维码的功能,在网上查了很久才解决问题.以此来记录下来解决问题的方法. 最开始找的方法是一个叫 php-zbarcode 的扩展,自己照着网上的安装步骤安装了 Image ...
- Java自学笔记
1.标识符:字母,数字,下划线,美元符组成,不可以已数字开头,并且严格区分大小写 2.变量 有三个元素描述变量,变量类型,变量名,变量值 如何命名变量:首字母为 字母:下划线:“$“符号,其余部分为 ...
- Zookeeper运维问题集锦
实际工作中用到Zookeeper集群的地方很多, 也碰到过各种各样的问题, 在这里作个收集整理, 后续会一直补充; 其中很多问题的原因, 解决方案都是google而来, 这里只是作次搬运工; 其实很多 ...
- MYSQL转换编码的解决方法
MYSQL转换编码的解决方法 一.在utf8的mysql下 得到中文‘游客’的gbk下的16进制编码 mysql> SELECT hex(CONVERT( '游客' USING gbk )); ...
- 关于HTTP协议学习(一)
一,目录结构 B/S 结构定义 URI (统一资源标志符) HTTP 协议 HTTP 请求报文 HTTP 响应报文 HTTP Methods HTTP Status Code 二,B/S,C/S 结构 ...
- [strongswan] strongswan是如何实现与xfrm之间的trap机制的
目录 strongswan与xfrm之间的trap机制 0. 1. 前言 2. 描述 2.1 none 2.2 trap 3. 实验与过程 3.1 trap实验 3.2 none实验 4 背景知识 5 ...
- std unorder_map insert 和 emplace的区别
std::unordered_map<int, int > map; map.insert(std::make_pair(, )); map.insert(std::make_pair(, ...