每日一题Day5
题解:
dp题目但是还是太菜了...
我们定义状态函数为前
i个元素中删去j个元素后得到的子序列数目,如果不考虑重复,就有。但是这样转移的话会有重复序列的情况出现,比如
1 2 1序列,删除和删除
是一样的结果。那么我们发现,出现重复的情况的前提是**当前元素
有重复元素且两者之间的元素和其中一个
全部被删除。**
于是可以更新一下转移方程:其中
past是上一次出现的位置。
AC代码:
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define inf -0x3f3f3f3f
#define me(a,b) memset(a,b,sizeof(a))
#define PII pair<int,int>
#define ull unsigned long long
#define ios std :: ios :: sync_with_stdio(false)
#define rep(i,a,b) for(int i = a;i <= b;i ++)
#define esp 1e-16
using namespace std;
const int maxn = 1e5 + 9;
const int mode = 1e9 + 7;
ll dp[maxn][12] = {};
int n, m, k;
int a[maxn] = {}, pre[maxn] = {};
int main()
{
ios;
while (cin >> n >> m >> k) {
me(dp, 0);
me(pre, -1);
rep(i, 1, n) cin >> a[i];
dp[0][0] = 1;
rep(i, 1, n) {
dp[i][0] = 1;
rep(j, 1, min(m, i)) {
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1] + mode) % mode;
if (pre[a[i]] != -1 && (i - pre[a[i]]) <= j) dp[i][j] = (dp[i][j] - dp[pre[a[i]] - 1][j - (i - pre[a[i]])] + mode) % mode;
}
pre[a[i]] = i;
}
cout << dp[n][m] << endl;
}
return 0;
} 
京公网安备 11010502036488号