1. 程式人生 > >Uva 10074【遞推dp】

Uva 10074【遞推dp】

idt lose str img ide mil -- msu nbsp

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

Uva 10074【遞推dp】