zoukankan      html  css  js  c++  java
  • USACO theme

      这道题的意思是给你一个长度不超过5000的串, 让你求解一个主题串, 其中主题串的定义是在这个串中重复出现过两次,没有重叠部分, 且两个串各减某个数后序列一样。。我们可以定义dp[i][j]为从i位置和j位置开始相同的串的长度, dp[i][j] = dp[i+1][j+1] + 1; 其中num[j+1]-num[i+1] = num[j]-num[i], 另外求出这个答案后还要记得判断是否重叠, 最后答案也要加1, 代码如下:

    /*
        ID: m1500293
        LANG: C++
        PROG: theme
    */
    
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    
    using namespace std;
    int num[5000+10];
    short dp[2][5010];   //dp[i][j]以i, j开始的最长相同子串
    
    int main()
    {
        freopen("theme.in", "r", stdin);
        freopen("theme.out", "w", stdout);
        int N;
        scanf("%d", &N);
        for(int i=1; i<=N; i++) scanf("%d", &num[i]);
        short res = 0;
        for(int i=N; i>=1; i--)
        {   memset(dp[i%2], 0, sizeof(dp[1]));
            for(int j=N; j>=1; j--)
            {
    
                if(j+1<=N && i+1<=N && num[j+1]-num[i+1]==num[j]-num[i]) dp[i%2][j] = dp[(i+1)%2][j+1] + 1;
                else dp[i%2][j] = 0;
                int x=j, y=j+dp[i%2][j]-1+1;
                if(!((i>=x&&i<=y)||(i+dp[i%2][j]-1+1>=x&&i+dp[i%2][j]-1+1<=y)))
                    res = max(res, dp[i%2][j]);
            }
            //printf("
    ");
        }
    
        if(res+1>=5) printf("%d
    ", res+1);
        else printf("0
    ");
        return 0;
    }
  • 相关阅读:
    第8周课下作业1(补)
    第八章课下测试
    POJ
    POJ
    HDU
    UVa
    UVa
    CodeForces
    ZOJ
    LightOJ
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5176944.html
Copyright © 2011-2022 走看看