【動態規劃】[luoguP1736]創意喫魚法

題目

發表了題解。。

我真的不知道我寫的搜索還是DP
反正都差不多吧 - -
怎麼搞呢
首先我們用三個數組 map[][]存圖 f[][]用來存如果矩陣的對角線是從左上到右下的話 能取得的最大對角線長度 dp[][]則是同理的右上到左下的矩陣
因爲每一個有魚的位置一開始本身就是一個矩陣 所以初始化當map[i][j]=1的時候 dp[i][j]和f[i][j]都爲1
然後在我們枚舉一個k 往前找 看看有沒有多餘的1 因爲我們要讓矩陣儘量的大且題目要求這個矩陣除了對角線之外其他地方都不能有1的 且k只需要枚舉到f(dp)[i - 1][j - 1]因爲再往前的之前搞f(dp)[i - 1][j - 1]已經枚舉過了 再枚舉反而會出亂子 然後就是如果滿足!map[i - k][j] && !map[i][j - k] && map[i - k][j - k]那麼這個矩陣就可以有i-k~i j-k~j那麼大 用一個tmp來記錄當前對角線增長了多少 最後f(dp)[i][j]再+=tmp一下 就完成了 這樣保證對於每一個有魚的點都能統計到以它爲末端的最大的對角線是左上到右下的正方形或者對角線是右上到左下的正方形的對角線長度(沒錯 我語文很差)
在過程中ans不斷更新最大值 最後輸出

代碼如下



#include<iostream>
#include<cstdio>
#include<cctype>

    using namespace std;
    #define in = read();
    typedef long long ll;
    typedef unsigned int ui;
    const ll size = 2500 + 10;

        int n , m;
        int map[size][size];
        int ans , tmp , tmp2;
        int f[size][size] , dp[size][size];

inline ll read(){
        ll num = 0 , f = 1;    char ch = getchar();

        while(!isdigit(ch)){
                if(ch == '-')   f = -1;
                ch = getchar();
        }
        while(isdigit(ch)){
                num = num*10 + ch - '0';
                ch = getchar();
        }

        return num*f;
}

int main(){
        n in;    m in;
        for(register int i=1;i<=n;i++)
                for(register int j=1;j<=m;j++){
                        map[i][j] in;
                        if(map[i][j]){
                                f[i][j] = 1;
                                dp[i][j] = 1;
                                ans = 1;
                        }
                }

        for(register int i=1;i<=n;i++)
                for(register int j=1;j<=m;j++){
                        if(map[i][j] && map[i - 1][j - 1]){
                                for(register int k=1;k<=f[i - 1][j - 1];k++){
                                        if(!map[i - k][j] && !map[i][j - k] && map[i - k][j - k])
                                                tmp ++;
                                        else    break;
                                }
                                f[i][j] += tmp;
                                ans = max(ans , f[i][j]);
                                tmp = 0;
                        }
                }
        for(register int i=1;i<=n;i++)
                for(register int j=1;j<=m;j++){
                        if(map[i][j] && map[i - 1][j + 1]){
                                for(register int k=1;k<=dp[i - 1][j + 1];k++){
//                                        cout<<k<<" "<<map[i - 1][j + 1] + 1<<" " <<i<<" "<<j<<endl;
                                        if(!map[i - k][j] && !map[i][j + k] && map[i - k][j + k])
                                                tmp ++;
                                        else    break;
                                }
                                dp[i][j] += tmp;
                                ans = max(ans , dp[i][j]);
                                tmp = 0;
                        }
                }
/*
        cout<<endl;
        for(register int i=1;i<=n;i++){
                for(register int j=1;j<=m;j++)
                        cout<<f[i][j]<<" ";
                cout<<endl;
        }
        cout<<endl;
        for(register int i=1;i<=n;i++){
                for(register int j=1;j<=m;j++)
                        cout<<dp[i][j]<<" ";
                cout<<endl;
        }*/
        printf("%d" , ans);
}
/*
4 6
0 0 1 0 1 0
0 1 0 1 0 0
1 0 0 0 1 1
0 1 0 1 1 0

10 10
0 0 1 0 1 0 1 1 1 1 
1 1 1 0 1 0 0 0 0 1
0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 0 1 1
0 0 0 0 0 1 0 0 1 0
0 0 0 0 1 0 0 0 1 1
0 0 0 1 0 0 0 0 1 1
0 0 1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 1 1
1 0 0 0 0 0 0 0 1 0
*/


//COYG
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章