HDU 2859 Phalanx(DP)

2 篇文章 0 订阅

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2859

题目大意:给定一个数字n,代表着一个n*n的字符矩阵,求解当前矩阵中从对称矩阵最大的大小(对称轴为从左下到右上)。

解析:利用dp[i][j],其含义为以当前点[i][j]作为左下顶点的最大的对称矩阵的大小;
例如:
4 ———————- 所对应的dp数组为:
zaba —————— 1 1 1 1
cbab —————— 1 2 2 1
abbc —————— 1 2 1 1
cacq ——————-3 1 1 1

状态转移方程为:
if(cnt > dp[i][j]) dp[i][j] = dp[i-1][j+1] + 1;
else dp[i][j] = cnt;
cnt为当前点的上方与右侧的字符匹配量.


AC代码如下:

#include <iostream>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <string>
#include <sstream>
#include <cctype>
#include <climits>
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <vector>
#include <iterator>
#include <algorithm>
#include <stack>
#include <functional>
//cout << "OK" << endl;
#define _clr(x,y) memset(x,y,sizeof(x))
#define _inf(x) memset(x,0x3f,sizeof(x))
#define pb push_back
#define mp make_pair
#define FORD(i,a,b) for (int i=(a); i<=(b); i++)
#define FORP(i,a,b) for (int i=(a); i>=(b); i--)
#define REP(i,n) for (int i=0; i<(n); i++)
using namespace std;
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const double EULER = 0.577215664901532860;
const double PI = 3.1415926535897932384626;
const double E = 2.71828182845904523536028;
typedef long long LL;
LL pow_mod(LL a,LL n,LL m)
{
    if(n == 0) return 1;
    LL x = pow_mod(a,n>>1,m);
    LL ans = x*x%m;
    if(n&1) ans = ans*a%m;
    return ans;
}
int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}


char str[1010][1010];
int dp[1010][1010];
int main(){
    int n;
    while(cin >> n && n){
        //输入字符矩阵 
        FORD(i,0,n-1){
            getchar();
            FORD(j,0,n-1){
                scanf("%c",&str[i][j]);
            }
        }
        int ans = 0;
        //对整个矩阵进行遍历 
        FORD(i,0,n-1){
            FORD(j,0,n-1){
                //如果这时候处理的是第一行的字符,其最大的对称矩阵的大小显然为1 
                if(i == 0) dp[i][j] = 1;
                else{
                    int a = i;
                    int b = j;
                    int cnt = 0;//cnt记录当前位置的上方与右方最大的匹配量 
                    while(str[a][j] == str[i][b]){
                        cnt++;
                        a--;
                        b++;
                        if(a < 0 || b > n) break;
                    }
                    //如果匹配量大于当前顶点右上方的匹配量,则当前点的最大对称矩阵大小加一 
                    if(cnt > dp[i-1][j+1]){
                        dp[i][j] = dp[i-1][j+1] + 1;
                    }
                    //如果不是,则当前顶点的最大对称矩阵的大小就是当前顶点的匹配量 
                    else dp[i][j] = cnt;
                }
                //记录下最大值即可 
                if(dp[i][j] > ans) ans = dp[i][j];
            }
        } 
        cout << ans << endl;
    }
    return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值