zoukankan      html  css  js  c++  java
  • 牛客网第一场E题 Removal

    链接:https://www.nowcoder.com/acm/contest/139/E
    来源:牛客网
    
    Bobo has a sequence of integers s1, s2, ..., sn where 1 ≤ si ≤ k.
    Find out the number of distinct sequences modulo (109+7) after removing exactly m elements.
    输入描述:
    The input consists of several test cases and is terminated by end-of-file.
    The first line of each test case contains three integers n, m and k.
    The second line contains n integers s1, s2, ..., sn.
    输出描述:
    For each test case, print an integer which denotes the result.
    示例1
    输入
    复制
    3 2 2
    1 2 1
    4 2 2
    1 2 1 2
    输出
    复制
    2
    4
    备注:
    * 1 ≤ n ≤ 105
    * 1 ≤ m ≤ min{n - 1, 10}
    * 1 ≤ k ≤ 10
    * 1 ≤ si ≤ k
    * The sum of n does not exceed 106.

    dp [i][j]:表示以i位子结尾删除j个字符的方案数。

    开一个nt[i][j] 表示从i开始,字符j的位子

    那么我们可以得到一个递推式。

    dp[nt[i][p]][nt[i][p]-i-1+j]+=dp[i][j];
    dp[i][j]可以转移到下一个位子;
    比如
    XXXCYYYC;
    那么我们删到xxx和xxxcyyy是一样
    所以我们每次找到下一个位子
    #include <iostream>
    #include<stdio.h>
    #include<string.h>
    #define ll long long
    #define mod 1000000007
    using namespace std;
    int nt[100005][15];
    int a[100005];
    int dp[100005][15];//以a[i]结尾的,删了 j个
    int main()
    {
        int n,m,k;
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
            }
            for(int i=1; i<=k; i++)
            {
                nt[n][i]=n+1;
            }
            for(int i=n; i>=1; i--)
            {
                for(int j=1; j<=k; j++)
                    nt[i-1][j]=nt[i][j];
                   nt[i-1][a[i]]=i;
            }
            memset(dp,0,sizeof dp);
            dp[0][0]=1;
             for(int i=0;i<=n;i++)
             {
                 for(int j=0;j<=m;j++)
                 {
                     for(int p=1;p<=k;p++)
                     {
                         int to=nt[i][p];
                         int shan=to-i-1;
                         if(shan+j<=m)
                         {
                             dp[to][shan+j]+=dp[i][j];
                             dp[to][shan+j]=dp[to][shan+j]%1000000007;
                         }
                     }
                 }
             }
             int ans=0;
             for(int i=0;i<=m;i++)
             {
                    ans=ans+dp[n-i][m-i];
                    ans=ans%1000000007;
             }
              cout<<ans<<endl;
    
        }
    
    
            return 0;
        }
  • 相关阅读:
    关于token的理解
    JavaScript 中 call()、apply()、bind() 的用法
    常用JS整理
    js里面for循环的++i与i++
    前端命名规范
    H5混合开发app常用代码
    jquery知识巩固
    水平垂直居中(固定宽不固定宽)
    css3新属性运用
    bug笔记(pc)
  • 原文地址:https://www.cnblogs.com/2014slx/p/9359782.html
Copyright © 2011-2022 走看看