1. 程式人生 > >洛谷1736創意吃魚法

洛谷1736創意吃魚法

題目背景

感謝@throusea 貢獻的兩組資料

題目描述

回到家中的貓貓把三桶魚全部轉移到了她那長方形大池子中,然後開始思考:到底要以何種方法吃魚呢(貓貓就是這麼可愛,吃魚也要想好吃法 ^_*)。她發現,把大池子視為01矩陣(0表示對應位置無魚,1表示對應位置有魚)有助於決定吃魚策略。

在代表池子的01矩陣中,有很多的正方形子矩陣,如果某個正方形子矩陣的某條對角線上都有魚,且此正方形子矩陣的其他地方無魚,貓貓就可以從這個正方形子矩陣“對角線的一端”下口,只一吸,就能把對角線上的那一隊鮮魚吸入口中。

貓貓是個貪婪的傢伙,所以她想一口吃掉儘量多的魚。請你幫貓貓計算一下,她一口下去,最多可以吃掉多少條魚?

輸入輸出格式

輸入格式:

 

有多組輸入資料,每組資料:

第一行有兩個整數n和m(n,m≥1),描述池塘規模。接下來的n行,每行有m個數字(非“0”即“1”)。每兩個數字之間用空格隔開。

對於30%的資料,有n,m≤100

對於60%的資料,有n,m≤1000

對於100%的資料,有n,m≤2500

 

輸出格式:

 

只有一個整數——貓貓一口下去可以吃掉的魚的數量,佔一行,行末有回車。

 

輸入輸出樣例

輸入樣例#1: 複製
4 6
0 1 0 1 0 0
0 0 1 0 1 0
1 1 0 0 0 1
0 1 1 0 1 0
輸出樣例#1: 複製
3

說明

右上角的

1 0 0
0 1 0
0 0 1

******DP題,這道題可以看成最大正方形的提高版,求兩種掃描線,上面那種是s陣列求左面的0個數,下面的那種是求s右面0的個數注意列數加或減1
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 int i,j,n,m,ans = 0,a[2505][2505],f[2505][2505],s[2505][2505],c[2505
][2505]; 7 int main() 8 { 9 scanf("%d %d",&n,&m); 10 for(i = 1;i <= n;i++) 11 { 12 for(j = 1;j <= m;j++) 13 { 14 scanf("%d",&a[i][j]); 15 if(a[i][j] == 0) 16 { 17 s[i][j] = s[i][j - 1] + 1; 18 c[i][j] = c[i - 1][j] + 1; 19 } 20 else 21 { 22 f[i][j] = min(f[i - 1][j - 1],min(s[i][j - 1],c[i - 1][j])) + 1; 23 } 24 ans = max(ans,f[i][j]); 25 } 26 } 27 memset(f,0,sizeof(f)); 28 memset(s,0,sizeof(s)); 29 for(i = 1;i <= n;i++) 30 { 31 for(j = m;j >= 1;j--) 32 { 33 if(a[i][j] == 0) 34 { 35 s[i][j] = s[i][j + 1] + 1; 36 c[i][j] = c[i - 1][j] + 1; 37 } 38 else 39 { 40 f[i][j] = min(f[i - 1][j + 1],min(s[i][j + 1],c[i - 1][j])) + 1; 41 } 42 ans = max(ans,f[i][j]); 43 } 44 } 45 printf("%d",ans); 46 return 0; 47 }