E - Removal(dp,去重)

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.

Input
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.

  • 1≤n≤105
  • 1≤m≤min{n−1,10}
  • 1≤k≤10
  • 1≤si≤k
  • The sum of n does not exceed 106.

Output
For each test case, print an integer which denotes the result.

Example
Input
3 2 2
1 2 1
4 2 2
1 2 1 2
Output
2
4
先不考虑重复情况:dp[i][j]=dp[i-1][j]+dp[i-1][j-1] 第i位数删去j个数
重复情况:如:123451 去掉12345和23451结果一样,即删去两个最近相同元素中间的所有元素
用f[i]记录距离i位置最近的相同元素的位置,下面用x简单替代。
去重:i=x-1 j=j-(i-x)即代表把中间元素全删掉
dp[i][j]-=dp[x-1][j-(i-x)]

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
int dp[100100][20],a[100100],w[20],f[100100];
int main()
{
    
    
    ios::sync_with_stdio(false);
    int n,m,k;
    while(cin>>n>>m>>k)
    {
    
    

        for(int i=1;i<=k;i++) w[i]=0;
        for(int i=1;i<=n;i++) f[i]=0;
        memset(dp,0,sizeof(dp)); 
        for(int i=1;i<=n;i++) 
		{
    
    
            cin>>a[i];
            f[i]=w[a[i]];w[a[i]]=i;
        }
        for(int i=0;i<=m;i++) dp[i][i]=1;//dp[i][0]不能合并,会超空间 
        for(int i=1;i<=n;i++)
		{
    
    
            dp[i][0]=1;
            for(int j=1;j<=m&&j<i;j++)
			{
    
    
				dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%mod;
				if(f[i]&&(j-(i-f[i]))>=0) 
				 dp[i][j]=(dp[i][j]-dp[f[i]-1][j-(i-f[i])]+mod)%mod;
			}
		}
        cout<<dp[n][m]<<endl;   
	}    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43540515/article/details/113060164
今日推荐