DP学习
DP关于方案数
luogu p1108
这是一个简单的DP,与方案数有一点关系
我们先看第一问,最大购买次数为最长下降序列长度。
然后我们要去处理方案数
d[i] 表示以 i 结尾时的方案数
我们考虑什么时候会有重复
当序列的最后一位相等并且序列长度相等,我们要删除重复的方案数
/***********************************************************
> File Name: LGP1108.cpp
> Author: lan_m
> QQ: 2867930696
> Created Time: 2021/9/13 8:06:19
> fighting for night
*******************************************************/
#include <bits/stdc++.h>
using namespace std;
int a[5100];
int f[5010];
int d[5010];
int n;
int maxn;
int main () {
scanf("%d",&n);
for (int i = 1;i <= n;i ++) scanf("%d",&a[i]);
// for (int i = 1;i <= n;i ++)f[i] = 1,d[i] = 1;
for (int i = 1; i<= n;i ++) {
for (int j = 1;j < i;j ++){
if(a[i] < a[j]) f[i] = max(f[i] , f[j] + 1);
}
if(f[i] == 0) f[i] = 1;
maxn = max ( maxn,f[i]);
for (int j = 1;j < i;j ++) {
if (f[i] == f[j] && a[i] == a[j])
d[j] = 0;
else if(f[i] == f[j] + 1 && a[i] < a[j]){
d[i] += d[j];
}
}
if(d[i] == 0) d[i] = 1;
}
int ans = 0;
for (int i = 1;i <= n;i ++) if(f[i] == maxn) ans += d[i];
printf("%d %d",maxn,ans);
return 0;
}
之后补充计数类DP的一些题