码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 3997] 组合数学

时间:2017-09-05 22:02:41      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:algo   nbsp   一个   bsp   inline   git   i++   str   efi   

题意

  给定 $n \times m$ 的网格图, 每个格子有 $w$ 个财宝.

  每次从左上角出发到右下角, 将途中经过的所有格子中的财宝至多拿一个.

  问最少多少次能拿完所有财宝.

  $n, m \le 1000$ .

 

分析

  根据 Dilworth 定理, 最少链划分 = 最大反链长度.

  从左下角到右上角进行 DP .

 

实现

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #include <algorithm>
 6 using namespace std;
 7 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 8 #define P(i, a, b) for (register int i = (a); i >= (b); i--)
 9 #define LL long long
10 inline int rd(void) {
11     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1;
12     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-0; return x*f;
13 }
14 
15 const int N = 1005;
16 
17 int n, m, w[N][N];
18 LL f[N][N];
19 
20 int main(void) {
21     #ifndef ONLINE_JUDGE
22         freopen("bzoj3997.in", "r", stdin);
23     #endif
24     
25     for (int nT = rd(); nT > 0; nT--) {
26         n = rd(), m = rd();
27         F(i, 1, n) F(j, 1, m) w[i][j] = rd();
28     
29         memset(f, 0, sizeof f);
30         P(i, n, 1)
31             F(j, 1, m) {
32                 f[i][j] = max(f[i][j-1], f[i+1][j]);
33                 f[i][j] = max(f[i][j], f[i+1][j-1] + w[i][j]);
34             }
35         printf("%lld\n", f[1][m]);
36     }
37     
38     return 0;
39 }

 

[BZOJ 3997] 组合数学

标签:algo   nbsp   一个   bsp   inline   git   i++   str   efi   

原文地址:http://www.cnblogs.com/Sdchr/p/7481812.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!