數據結構之dp與字符串哈希

dp-LeetCode 221. 最大正方形

在一個由 0 和 1 組成的二維矩陣內,找到只包含 1 的最大正方形,並返回其面積。

示例:

輸入: 

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

輸出: 4

dp(i, j)=min(dp(i−1, j), dp(i−1, j−1), dp(i, j−1))+1,當然還可以優化成一維數組,減小空間複雜度

const int maxn=1e3+5;
int dp[maxn][maxn];
class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        if(matrix.empty()) return 0;
        int row=matrix.size(),col=matrix[0].size();
        int ans=0;
        for(int i=0;i<row;i++)
        for(int j=0;j<col;j++){
            if(matrix[i][j]=='0') dp[i][j]=0;
            else{
                if(i==0||j==0) {
                    dp[i][j]=(matrix[i][j]=='1'?1:0);
                    ans=max(ans,dp[i][j]);
                }
                else {
                    dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;
                    ans=max(ans,dp[i][j]);
                }
            }
        }
        return ans*ans;
    }
};

dp-hdu 1423.Greatest Common Increasing Subsequence

Problem Description

This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence.

Input

Each sequence is described with M - its length (1 <= M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence itself.

Output

output print L - the length of the greatest common increasing subsequence of both sequences.

Sample Input

1

 

5

1 4 2 5 -12

4

-12 1 2 4

Sample Output

2

求兩個序列的最長上升子序列長度,dp[j]表示[0,i]與[0,j]的最長上升子序列長度

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e2+5;
int a[maxn],b[maxn],dp[maxn];
int main()
{
    int t,m,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&m);
        for(int i=0; i<m; i++) scanf("%d",&a[i]);
        scanf("%d",&n);
        for(int i=0; i<n; i++) scanf("%d",&b[i]);
        memset(dp,0,sizeof(dp));
        for(int i=0; i<m; i++)
        {
            int maxi=0;
            for(int j=0; j<n; j++)
            {
                if(a[i]==b[j])
                    dp[j]=max(maxi+1,dp[j]);
                if(a[i]>b[j])
                    maxi=max(maxi,dp[j]);
            }
        }
        int ans=0;
        for(int i=0; i<n; i++) ans=max(ans,dp[i]);
        printf("%d\n",ans);
        if(t) printf("\n");
    }
}

字符串哈希-SCU 4438.Censor

frog is now a editor to censor so-called sensitive words (敏感詞).

She has a long text p. Her job is relatively simple -- just to find the first occurence of sensitive word w and remove it.

frog repeats over and over again. Help her do the tedious work.

Input

The input consists of multiple tests. For each test:

The first line contains 1 string w. The second line contains 1 string p.

(1≤length of w,p≤5⋅10^6 1≤length of w,p≤5⋅10^6, w,pw,p consists of only lowercase letter)

Output

For each test, write 1 string which denotes the censored text.

Sample Input

abc
aaabcbc
b
bbb
abc
ab

Sample Output

a

ab

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int maxn=5e6+5;
ull po[maxn],Hash[maxn];
char ans[maxn];
const int seed=131;
string w,p;
int lenw,lenp;
void init(){
    po[0]=1;
    for(int i=1;i<=maxn;i++) po[i]=po[i-1]*seed;
}
void getHashw(){
    Hash[0]=w[0];
    for(int i=1;i<lenw;i++)
        Hash[i]=Hash[i-1]*seed+w[i];
}
ull getHash(int le,int ri){
    if(le==0) return Hash[ri];
    return Hash[ri]-Hash[le-1]*po[ri-le+1];
}
int main(){

    init();
    while(cin>>w>>p){
        lenw=w.size(),lenp=p.size();
        getHashw();
        ull temp=Hash[lenw-1];
        int len=0;
        for(int i=0;i<lenp;i++){
            ans[len++]=p[i];
            if(len==1){
                Hash[0]=p[i];
            }
            else{
                Hash[len-1]=Hash[len-2]*seed+p[i];
            }
            if(len>=lenw){
                if(getHash(len-lenw,len-1)==temp){
                    len-=lenw;
                }
            }
        }
        ans[len]='\0';
        printf("%s\n",ans);
    }
}

 

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