hdu 1505 && hdu1506 &&hdu 2830 && 2870 总结---------DP之状图选最大矩形

/*

多谢了“闭眼,睁眼” 同学给我一套dp专题,不然真是没接触过这种题型。

做个4个简单的,很高兴有所收获。

2013-08-06

/*


HDU 1506

最基础的一道题目,其主要精髓就在于两个数组 l[i],r[i];

其中,l[i]用来存储第i个矩形的左边界,r[i]存储的是第i个矩形的右边界,也就是说对于任意的 l[i]<=x<=r[i]都有a[x]>=a[i]  ;

  1 #include<stdio.h>
  2 #include<string.h>
  3 #define Max(x,y) (x>y?x:y)
  4 #define max 100000+10
  5 
  6 typedef __int64 LL;
  7 
  8 LL a[max];
  9 int l[max],r[max],n;
 10 
 11 int main(){
 12     while(~scanf("%d",&n)&&n){
 13         for(int i=1;i<=n;i++){
 14             scanf("%I64d",&a[i]);
 15             l[i]=r[i]=i;
 16         }
 17         a[0]=a[n+1]=-1;
 18         LL ans=0;
 19         for(int i=1;i<=n;i++){     //计算数组l
 20             while(a[l[i]-1]>=a[i]){
 21                 l[i]=l[l[i]-1];
 22             }
 23         }
 24         for(int i=n;i>=1;i--){    //计算数据r
 25             while(a[r[i]+1]>=a[i]){
 26                 r[i]=r[r[i]+1];
 27             }
 28         }
 29         for(int i=1;i<=n;i++){
 30             ans=Max(ans,a[i]*(r[i]-l[i]+1));
 31         }
 32         printf("%I64d
",ans);
 33     }
 34 }
 35 
 36 ----------------------------------------------------------------------------
 37 
 38 HDU 1505
 39 
 40 
 41 #include<stdio.h>
 42 #include<string.h>
 43 #include<vector>
 44 using namespace std;
 45 #define Max(x,y) (x>y?x:y)
 46 #define max 2000+10
 47 
 48 int  map[max][max];
 49 int n,m,l[max/2],r[max/2];
 50 int dp[max];
 51 
 52 int DP(){
 53     for(int i=1;i<=m;i++){
 54         l[i]=r[i]=i;
 55     }
 56     dp[0]=dp[m+1]=-1;
 57     for(int i=1;i<=m;i++){
 58         while(dp[l[i]-1]>=dp[i]){
 59             l[i]=l[l[i]-1];
 60         }
 61     }
 62     for(int i=m;i>=1;i--){
 63         while(dp[r[i]+1]>=dp[i]){
 64             r[i]=r[r[i]+1];
 65         }
 66     }
 67     int res=0;
 68     for(int i=1;i<=n;i++){
 69         res=Max(res,dp[i]*(r[i]-l[i]+1));
 70     }
 71     return res;
 72 }
 73 
 74 int main(){
 75     int t;
 76     scanf("%d",&t);
 77     while(t--){
 78         int ans=0;
 79         scanf("%d%d",&n,&m);
 80         memset(dp,0,sizeof(dp));
 81         for(int i=1;i<=n;i++){
 82 //            getchar();
 83             for(int j=1;j<=m;j++){
 84                 char c[max];
 85                 scanf("%s",c);
 86                 if(c[0]=='F'){
 87                     map[i][j]=1;
 88                     dp[j]++;
 89                 }
 90                 else{
 91                     map[i][j]=0;
 92                     dp[j]=0;
 93                 }
 94             }
 95             ans=Max(ans,DP());
 96         }
 97         printf("%d
",ans*3);
 98     }
 99 }
100 ===================================================================================
101 HDU 2830
102 
103 
104 #include<stdio.h>
105 #include<string.h>
106 #include<algorithm>
107 using namespace std;
108 #define Max(x,y) (x>y?x:y)
109 #define max 1000+5
110 
111 char map[max][max];
112 int dp[max],temp[max],n,m;
113 
114 int DP(){
115     int res=0;
116     memcpy(temp,dp,sizeof(dp));
117     sort(temp+1,temp+m+1);
118     for(int i=m;i>=1;i--){
119         if(temp[i]){
120             res=Max(res,temp[i]*(m-i+1));
121         }
122     }
123     return res;
124 }
125 
126 int main(){
127     while(~scanf("%d%d",&n,&m)){
128         int ans=0;
129         memset(dp,0,sizeof(dp));
130         for(int i=1;i<=n;i++){
131             scanf("%s",map[i]+1);
132             for(int j=1;j<=m;j++){
133                 if(map[i][j]=='1'){
134                     dp[j]++;
135                 }
136                 else{
137                     dp[j]=0;
138                 }
139             }
140             ans=Max(ans,DP());
141         }
142         printf("%d
",ans);
143     }
144 }
145 
146 
147 =================================================================================
148 
149 HDU 2870
150 
151 
152 #include<stdio.h>
153 #include<string.h>
154 #define Max(x,y) (x>y?x:y)
155 #define max 1000+5
156 
157 int n,m,dp[max],l[max],r[max];
158 char map[max][max],temp[max][max];
159 
160 void change(char a,char b,char c,char d){
161     for(int i=1;i<=n;i++){
162         for(int j=1;j<=m;j++){
163             temp[i][j]=map[i][j];
164             char& t=temp[i][j];
165             if(t==b||t==c||t==d){
166                 t=a;
167             }
168         }
169     }
170 }
171 
172 int work(){
173     for(int i=1;i<=m;i++){
174         l[i]=r[i]=i;
175     }
176     dp[0]=dp[m+1]=-1;
177     for(int i=1;i<=m;i++){
178         while(dp[l[i]-1]>=dp[i]){
179             l[i]=l[l[i]-1];
180         }
181     }
182     for(int i=m;i>=1;i--){
183         while(dp[r[i]+1]>=dp[i]){
184             r[i]=r[r[i]+1];
185         }
186     }
187     int ans=0;
188     for(int i=1;i<=m;i++){
189         ans=Max(ans,dp[i]*(r[i]-l[i]+1));
190     }
191     return ans;
192 }
193 
194 int DP(char c){
195     int ans=0;
196     memset(dp,0,sizeof(dp));
197     for(int i=1;i<=n;i++){
198         for(int j=1;j<=m;j++){
199             if(temp[i][j]==c){
200                 dp[j]++;
201             }
202             else{
203                 dp[j]=0;
204             }
205         }
206         ans=Max(ans,work());
207     }
208     return ans;
209 }
210 
211 int solve(){
212     int ans=0;
213     change('a','w','y','z');
214     ans=Max(ans,DP('a'));
215     change('b','w','x','z');
216     ans=Max(ans,DP('b'));
217     change('c','x','y','z');
218     ans=Max(ans,DP('c'));
219     return ans;
220 }
221 
222 int main(){
223     while(~scanf("%d%d",&n,&m)){
224         for(int i=1;i<=n;i++){
225             getchar();
226             for(int j=1;j<=m;j++){
227                 scanf("%c",&map[i][j]);
228             }
229         }
230         int ans=solve();
231         printf("%d
",ans);
232     }
233 }


原文地址:https://www.cnblogs.com/Stomach-ache/p/3703214.html