Removal

题意:一个长为n(1e5)的序列,序列中每个数<=k,现在删除m(<=10)个位置的数 。问有多少种不同的序列

思路:

DP。设dp[i][j]为到第i个位置,删除j个有多少个不同的序列. 接下来就去找后面跟1~k是不是存在即可。

#include<bits/stdc++.h>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+5;
const int MOD=1e9+7;
template <class T>
bool sf(T &ret){ //Faster Input
 
    char c; int sgn; T bit=0.1;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    if(c==' '||c=='\n'){ ret*=sgn; return 1; }
    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
    ret*=sgn;
    return 1;
}
int a[N];
int nt[N][20];
ll dp[N][20];
int pos[20];
int cnt[11];
int n,m,k;
void init(){
    memset(pos,0,sizeof pos);
    memset(cnt,0,sizeof cnt);
    for(int i = 0; i <= n; i++)
        for(int j = 0; j <= 10; j++)
            dp[i][j] = nt[i][j] = 0;
}
int main(void){
 
    while((scanf("%d%d%d",&n,&m,&k))==3){
        init();
 
        for(int i=1;i<=n;i++)   sf(a[i]);
//        for(int i=1;i<=k;i++)
//            if(cnt[i])  dp[1][0]++;
        for(int i=n;i>=0;i--){
            for(int j=1;j<=k;j++){
                nt[i][j]=pos[j];
            }
            pos[a[i]]=i;
        }
//        for(int j=1;j<=k;j++)   cout <<"~"<< nt[1][j]<<endl;
        dp[0][0]=1;
        for(int i=0;i<=n;i++){
            for(int j=0;j<=m;j++){
                for(int num=1;num<=k;num++){
 
                    if(nt[i][num]-i-1+j>m || !nt[i][num])  continue;
                    dp[nt[i][num]][nt[i][num]-i-1+j]+=dp[i][j];
                    dp[nt[i][num]][nt[i][num]-i-1+j]%=MOD;
//                    cout <<i <<" "<<j<<" "<<k<<endl;
                }
            }
        }
//        cout <<"debug"<<endl;
        ll ans=0;
        for(int i=n;i>=1;i--){
            if(m-(n-i)>=0)   ans=(ans+dp[i][m-(n-i)])%MOD;
        }
        ans%=MOD;
        printf("%lld\n",ans);
    }
    return 0;
}