zoukankan      html  css  js  c++  java
  • Good Bye 2015 D

    题意:给你一个数字组成的字符串,把它分成几个子串,使得每个串组成的数,没有前导0,且位置在前的字符串组成的数要严格小于位置在后的字符串,问你有多少种不同的分法。

    思路:LCP+dp

    转移方程:dp [ i][ j] +=dp[ i-j][k]( 1 <=k <=j-1)用sum数组代表总和。

    dp[ i][ j] 表示以第i个位置为结尾的最后一块长度为 j 的字符的分法数,则最后一块的起点是i-j+1,前一块等长度j的起点是i-j+1-j;若lcp[l][r]<j&&s[l+lcp[l][r]]<s[r+lcp[l][r]],则 dp[i][j]=dp[i][j]+dp[i-j][j]。

     1 #include<iostream>
     2 #include<string>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cstdio>
     6 #include<set>
     7 #include<map>
     8 #include<vector>
     9 #include<cstring>
    10 #include<stack>
    11 #include<cmath>
    12 #include<queue>
    13 #include <bits/stdc++.h>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define ll long long
    17 #define clc(a,b) memset(a,b,sizeof(a))
    18 const int maxn=1000000;
    19 const int mod=1e9+7;
    20 
    21 int t;
    22 int sum[5010][5010];
    23 int dp[5010][5010];
    24 int lcp[5010][5010];
    25 char s[5010];
    26 
    27 void init()
    28 {
    29     for(int i=t; i>=1; i--)
    30     {
    31         for(int j=t; j>i; j--)
    32         {
    33             if(s[i]==s[j])
    34                 lcp[i][j]=1+lcp[i+1][j+1];
    35             else
    36                 lcp[i][j]=0;
    37         }
    38     }
    39 }
    40 int main()
    41 {
    42     while(~scanf("%d",&t))
    43     {
    44         scanf("%s",s+1);
    45         clc(sum,0);
    46         clc(dp,0);
    47         clc(lcp,0);
    48         init();
    49         dp[0][0]=1;
    50         for(int i=0; i<=t; i++)
    51             sum[0][i]=1;
    52         for(int i=1; i<=t; i++)
    53         {
    54             for(int j=1; j<=i; j++)
    55             {
    56                 if(s[i-j+1]=='0')
    57                     continue;
    58                 dp[i][j]=(dp[i][j]+sum[i-j][j-1])%mod;
    59                 int l=i-j+1-j;
    60                 int r=i-j+1;
    61                 if(l<1)
    62                     continue;
    63                 if(lcp[l][r]<j&&s[l+lcp[l][r]]<s[r+lcp[l][r]])
    64                     dp[i][j]=(dp[i][j]+dp[i-j][j])%mod;
    65             }
    66             for(int j=1; j<=t; j++)
    67                 sum[i][j]=(sum[i][j-1]+dp[i][j])%mod;
    68         }
    69         ll ans=0;
    70         for(int i=1; i<=t; i++)
    71             ans=(ans+dp[t][i])%mod;
    72         printf("%I64d
    ",ans);
    73         //cout<<ans<<endl;
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    求二维数组的最大子集和
    电梯调度《二》
    电梯调度问题
    BIEE 通过提示器选择展示列(列名接收表示变量)
    BIEE时间序列函数
    Python学习笔记(三)
    Python学习笔记(二)
    Python学习笔记(一)
    BIE前台常用设置
    BIEE 连接BW query query结构 引用
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5155975.html
Copyright © 2011-2022 走看看