Uva 10074【递推dp】

UVa 10074

题意:求01矩阵的最大子0矩阵。

http://www.csie.ntnu.edu.tw/~u91029/MaximumSubarray.html#2

这里说的很清楚。先求Largest Empty Interval,枚举每个点为矩形的右下角。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAXN = 107;
 7 int Map[MAXN][MAXN], width[MAXN][MAXN];
 8 int row, col;
 9
10 int main()
11 {
12     while (cin>>row>>col&&!(row==0&&col==0))
13     {
14         int ans = 0;
15         for(int i=1;i<=row;i++)
16             for (int j = 1; j <= col; j++) {
17                 cin >> Map[i][j];
18                 if (Map[i][j]) width[i][j] = 0;
19                 else width[i][j] = width[i][j - 1] + 1;
20             }
21         for (int i = 1; i <= row; i++)
22         {
23             for (int j = 1; j <= col; j++) {
24                 int w = 1e9;
25                 for (int h = 1; i - h + 1 > 0; h++) {
26                     if (Map[i][j]) break;
27                     w = min(w, width[i - h + 1][j]);
28                     ans = max(ans, w*h);
29                 }
30             }
31         }
32         cout << ans << endl;
33     }
34     return 0;
35 }

按照下一个更高效的算法写,不知道为什么会WA,可能是哪里有问题。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAXN = 107;
 7 int Map[MAXN][MAXN];
 8 int wl[MAXN], wr[MAXN];
 9 int h[MAXN], l[MAXN], r[MAXN];
10 int row, col;
11
12 int main()
13 {
14     while (scanf("%d%d", &row, &col) == 2, !(row == 0 && col == 0))
15     {
16         int ans = 0;
17         for (int i = 1; i <= row; i++)
18             for (int j = 1; j <= col; j++)
19                 scanf("%d", &Map[i][j]);
20         for (int i = 1; i <= row; i++)
21         {
22             for (int j = 1; j <= col; j++)
23                 if (Map[i][j]) wl[j] = 0;
24             else wl[j] = wl[j - 1] + 1;
25
26             for (int j = col; j >= 1; j--)
27                 if (Map[i][j]) wr[j] = 0;
28             else wr[j] = wr[j + 1] + 1;
29
30             for (int j = 1; j <= row; j++)
31                 if (Map[i][j]) h[j] = 0;
32             else h[j] = h[j] + 1;
33
34             for (int j = 1; j <= col; j++)
35                 if (r[j] == 0) r[j] = wr[j];
36             else r[j] = min(wr[j], r[j]);
37
38             for (int j = 1; j <= col; j++)
39                 if (l[j] == 0) l[j] = wl[j];
40             else l[j] = min(wl[j], l[j]);
41
42             for (int j = 1; j <= col; j++)
43                         ans = max(ans, (l[j] + r[j] - 1)*h[j]);
44         }
45         printf("%d\n", ans);
46     }
47     return 0;
48 }

WA1

最高效的按照栈那种方式写也是WA。。。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stack>
 6 using namespace std;
 7 const int MAXN = 107;
 8 int a[MAXN][MAXN], h[MAXN][MAXN];
 9 int col, row;
10
11 int main()
12 {
13     while (cin >> row >> col)
14     {
15         if (!col && !row) break;
16         for (int i = 1; i <= row; i++)
17             for (int j = 1; j <= col; j++)
18                 cin >> a[i][j];
19         memset(h, 0, sizeof(h));
20         for (int i = 1; i <= row; i++)
21             for (int j = 1; j <= col; j++)
22                 if (a[i][j]) h[i][j] = 0;
23                 else h[i][j] = h[i - 1][j] + 1;
24
25                 stack<int> st;
26                 int area;
27                 int mx = 0;
28                 for (int i = 1; i <= row; i++)
29                 {
30                     int j;
31                     for (j = 1; j <= col;) {
32                         if (st.empty() || h[i][st.top()] <= h[i][j])
33                             st.push(j++);
34                         else {
35                             int top = st.top();
36                             st.pop();
37                             if (st.empty())
38                                 area = h[i][top] * j;
39                             else
40                                 area = h[i][top] * (j - st.top() - 1);
41                             mx = max(mx, area);
42                         }
43                     }
44                     while (!st.empty())
45                     {
46                         int top = st.top();
47                         st.pop();
48                         if (st.empty()) area = h[i][top] * j;
49                         else
50                             area = h[i][top] * (j - st.top() - 1);
51                         mx = max(mx, area);
52                     }
53                 }
54                 cout << mx << endl;
55     }
56     return 0;
57 }

WA2

时间: 2024-10-11 08:44:04

Uva 10074【递推dp】的相关文章

递推DP UVA 607 Scheduling Lectures

题目传送门 题意:教授给学生上课,有n个主题,每个主题有ti时间,上课有两个限制:1. 每个主题只能在一节课内讲完,不能分开在多节课:2. 必须按主题顺序讲,不能打乱.一节课L时间,如果提前下课了,按照时间多少,学生会有不满意度.问最少要几节课讲完主题,如果多种方案输出不满意度最小的 分析:dp[i]表示前i个主题最少要多少节课讲完,那么这个主题可能和上个主题在同一节课讲或者多开新的一节课讲,状态转移方程:看代码:优先满足节数少的情况 收获:普通的递推DP 代码: /**************

hdu 1284 钱币兑换问题 (递推 || DP || 母函数)

钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5069    Accepted Submission(s): 2868 Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于32768. Outpu

D. Caesar&#39;s Legions 背包Dp 递推DP

http://codeforces.com/problemset/problem/118/D 设dp[i][j][k1][k2] 表示,放了i个1,放了j个2,而且1的连续个数是k1,2的连续个数是k2 如果这样写,用dfs写是很简单的.但是超时,我记忆化不到 如果用递推写,对于每一个状态,更新到下一个状态. 如果放的是1,那么新的状态是dp[i + 1][j][k1 + 1][0]也就是,用多了一个1,而且连续的个数也增加了.同时,2的连续个数就打破了,变成了0 这种枚举旧状态,更新下一个状态

递推DP URAL 1031 Railway Tickets

题目传送门 1 /* 2 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 3 注意:s1与s2大小不一定,坑! 4 详细解释:http://blog.csdn.net/kk303/article/details/6847948 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <s

递推DP URAL 1119 Metro

题目传送门 1 /* 2 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 3 递推DP:仿照JayYe,处理的很巧妙,学习:) 4 好像还要滚动数组,不会,以后再补 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cmath> 10 #include <cs

Code Force 429B Working out【递推dp】

Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and mcolumns. Let number a[i][j] represents the calories burned by performing workout at the

CodeForces Round#229 DIV2 C 递推DP

对这道题目也只好说呵呵了,没注意k的范围最大才10,所以昨晚纠结了很久,没什么好的方法来处理,后来无奈想去翻翻题解,发现人家开头就来了句,因为k的范围比较小 所以.........我只好暂停马上回头看看题目,是的,k比较小所以完全可以先在询问前预处理DP一遍, DP就比较清晰了,dp[i][j]  (i>=0 && i<k,,,,j>=i && j <=n)代表意义呢 以i为开头的  区间[1,j]注意 是 1~j的 所需要的操作数,题目问的是最小操

[递推dp] zoj 3747 Attack on Titans

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5170 Attack on Titans Time Limit: 2 Seconds      Memory Limit: 65536 KB Over centuries ago, mankind faced a new enemy, the Titans. The difference of power between mankind and their newf

递推DP URAL 1353 Milliard Vasya&#39;s Function

题目传送门 1 /* 2 题意:1~1e9的数字里,各个位数数字相加和为s的个数 3 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 4 状态转移方程:dp[i][j] += dp[i-1][j-k],为了不出现负数 5 改为:dp[i][j+k] += dp[i-1][j] 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 #include <algorithm

递推DP URAL 1260 Nudnik Photographer

题目传送门 1 /* 2 递推DP: dp[i] 表示放i的方案数,最后累加前n-2的数字的方案数 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cmath> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e4 + 10; 11 const int INF = 0x3f3f3f3f; 12 int