【bzoj3997】[TJOI2015]组合数学
2017-04-11 16:12
381 查看
题目链接
每组数据第一行为正整数N,M代表网格图有N行M列,接下来N行每行M个非负整数,表示此格子中财宝数量,0代表没有
3 3
0 1 5
5 0 0
1 0 0
头一次知道这个定理居然还有个名字。
那么这题就是求最大点独立集,显然是一个从右上到左下的点的集合。
直接DP求解就好了。
Description
给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走。问至少走多少次才能将财宝捡完。此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走多少次才能把财宝全部捡完。Input
第一行为正整数T,代表数据组数。每组数据第一行为正整数N,M代表网格图有N行M列,接下来N行每行M个非负整数,表示此格子中财宝数量,0代表没有
Output
输出一个整数,表示至少要走多少次。Sample Input
13 3
0 1 5
5 0 0
1 0 0
Sample Output
10HINT
N<=1000,M<=1000.每个格子中财宝数不超过10^6题解
Dilworth定理:DAG的最小链覆盖=最大点独立集。头一次知道这个定理居然还有个名字。
那么这题就是求最大点独立集,显然是一个从右上到左下的点的集合。
直接DP求解就好了。
#include<bits/stdc++.h> using namespace std; inline int read(){ int x = 0, f = 1; char c = getchar(); while(!isdigit(c)) { if(c == '-') f = -1; c = getchar(); } while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x * f; } typedef long long ll; const int N = 1000 + 10; int a , n, m, t; ll f ; void init(){ n = read(), m = read(); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) a[i][j] = read(); memset(f, 0, sizeof(f)); } void work(){ t = read(); while(t--){ init(); for(int i = 1; i <= n; i++) for(int j = m; j >= 1; j--) f[i][j] = max(f[i-1][j+1] + a[i][j], max(f[i-1][j], f[i][j+1])); printf("%lld\n", f [1]); } } int main(){ work(); return 0; }
相关文章推荐
- BZOJ 3997: [TJOI2015]组合数学 [偏序关系 DP]
- [BZOJ 3997] [TJOI 2015] 组合数学
- BZOJ 3997 TJOI2015 组合数学
- 【BZOJ】3997: [TJOI2015]组合数学
- bzoj3997[TJOI2015]组合数学
- 【bzoj3997】[TJOI2015]组合数学 Dilworth定理结论题+dp
- 【bzoj3997】【TJOI2015】【组合数学】【dp】
- 【BZOJ 3997】 3997: [TJOI2015]组合数学 (DP| 最小链覆盖=最大点独立集)
- bzoj 3997: [TJOI2015]组合数学
- BZOJ3997: [TJOI2015]组合数学
- BZOJ 3997 TJOI2015 组合数学 Dilworth定理
- bzoj 3997: [TJOI2015]组合数学 dp
- bzoj3997 [TJOI2015]组合数学
- BZOJ 3997 [TJOI 2015 组合数学] 解题报告
- BZOJ 3997: [TJOI2015]组合数学
- bzoj3997 [TJOI2015]组合数学
- 【BZOJ 3997】: [TJOI2015]组合数学
- [bzoj3997] [TJOI2015]组合数学
- [BZOJ3997][TJOI2015]组合数学(Dilworth定理+DP)
- 【BZOJ3997】[TJOI2015]组合数学 最长反链