牛客网暑期ACM多校训练营(第一场)E.Removal
昨天下午,牛客多校第一场,开局两道题,之后盯上了这题,一直挂机到比赛结束,
本蒟蒻挂机期间机队友推出了A题的规律,最后3题gg
赛后看了眼榜
葫芦爷真的
赛时想的dp[i][j]是枚举到第i个长度为j的方案数,然后就转移不出来了,emmmmm
赛后看了题解pdf,发现挂机期间队友给的思路“dp[i][j]=长度为i以数字j为结尾的方案数”是正解
然后这个思路被我直接否决了,对不起队友orz
按照这个思路继续下去,我们再定义ans[len]表示长度为len的方案数
每次一个循环更新之后都要同时更新,因为这个时候的数值已经变化,
而我们每次更新都要求更新时所用的为最临近一次的方案数
所以要及时更新 长度为以结尾的方案数应该等于长度为的方案数
其实就是相当于长度为的串后面再加一个字符
for(int i=1; i<=n; i++)
{
for(int j=i; j>=max(1,i-m); j--)
{
ans[j]=(ans[j]+ans[j-1]-Next[j][a[i]])%mod;
Next[j][a[i]]=ans[j-1];
}}
由于m最大也只有10
我们暴力的去更新ans[len]的时间复杂度也只有
最后,就算知道正解了的我,在昨晚还是疯狂wa 50%
早上再一看代码,简直石乐志,没加mod直接取模会有负数啊..........
加了个mod再膜直接ac.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#include<limits.h>
#include<string.h>
#include<map>
#include<list>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long LL;
#define inf int(0x3f3f3f3f)
#define mod ll(1e9+7)
#define eps double(1e-7)
#define pi acos(-1.0)
#define lson root << 1
#define rson root << 1 | 1
int n,m,k;
int a[100005];
int Next[100005][15];
ll ans[100005];
void init()
{
memset(Next,0,sizeof(Next));
memset(ans,0,sizeof(ans));
ans[0]=1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin>>n>>m>>k)
{
k=n-m;
for(int i=1; i<=n; i++)
cin>>a[i];
init();
for(int i=1; i<=n; i++)
{
for(int j=i; j>=max(1,i-m); j--)
{
ans[j]=(ans[j]+ans[j-1]-Next[j][a[i]])%mod;
Next[j][a[i]]=ans[j-1];
}
}
cout<<(ans[k]+mod)%mod<<endl;
}
}