POJ 1952 DP LIS求方案数
来源:互联网 发布:淘宝usa商城卖假货? 编辑:程序博客网 时间:2024/05/16 17:10
题意:给一个序列,求最长不上升子序列长度以及有多少个这样的子序列。注意:看起来相同的子序列被算作一种方案。例如:421421的方案为442,441,422,421,411五种。
对于需要求方案数的LIS,求长度时就老老实实用O(n^2)的DP算法吧。
f[i]表示以i为最后一个数的最长不上升子序列,if(a[i] <= a[j]) f[i] = max(f[i], f[j]+1),而max{f[i]}就是第一问的答案。这个很好说。
主要是方案数,题目要求看起来相同的是被算作一种的,我们先设d[i][j]为以i结尾,不上升子序列的长度为j的方案数。如果没有之前那个要求,那么d[i][j] = ∑ d[k][j-1](k < i && a[i] <= a[j])。
但是考虑到题目的要求,我们需要进行判重,可以这么想:在一个序列a1,a2……an中,如果有ai == aj(i < j),那么d[j][t]肯定包括所有的d[i][t](0<t<=f[i])。也就是说我们对每个数本身进行判重,对于k,需要逆序枚举,如果枚举过将vis[a[k]]标记为1,我们只讲vis[a[k]] == 0的加到d[i][j]中即可,题目中也说明了数的大小是1<<16以内的,所以bool型数组是开得下的。
另外需要注意,在递归的过程中,如果d[i1][j1]枚举过k,把vis[a[k]]设为1,但是在另一个状态d[i2][j2](i2>k,i1>k)中,a[k]这个数是可以被再次访问的,就是说,对于每个d[i][j]都有独立的一个vis数组,但是在递归中是开不下的,会RE,所以就需要一个小技巧:每次递归开始就memset一下,相当于新声明了一个vis数组,当需要d[i][j] += d[k][j-1]时,先递归访问dp(k,j-1),再将vis[a[k]]设为1即可。
最后输出答案是d[n+1][ans+1],我们假定a[n+1]是一个最小的数,最长不上升子序列长度加1。
或者直接写个循环,把长度为ans的累加即可,这个与dp(n+1,ans+1)这一层递归是等价的。
#include <cstdio>#include <algorithm>#include <cstring>using namespace std;int n, ans, a[5005], f[5005], d[5005][5005];bool vis[(1<<16)+5];int dp(int i, int j){memset(vis, 0, sizeof vis);if(d[i][j]) return d[i][j];if(j == 1) return d[i][j] = 1;for(int k = i-1; k; k--){if(!vis[a[k]] && a[k] > a[i] && f[k] == j-1)d[i][j] += dp(k, j-1), vis[a[k]] = 1;}return d[i][j];}int main(){scanf("%d", &n);for(int i = 1; i <= n; i++){scanf("%d", a+i);f[i] = 1;for(int j = 1; j < i; j++)if(a[j] > a[i]) f[i] = max(f[i], f[j]+1);ans = max(ans, f[i]);}printf("%d %d", ans, dp(n+1, ans+1));}
0 0
- POJ 1952 DP LIS求方案数
- HDU5119【dp背包求方案数】
- 铺地板状压DP求方案数
- poj 2533 DP(LIS)
- poj 1836 dp lis
- POJ 3670 DP LIS?
- poj-3616 DP,LIS
- [DP-LIS] POJ 2533
- poj 1837 dp推方案数
- POJ 1631 nlogn求LIS
- POJ 1836 Alignment DP(LIS)
- poj 1836 Alignment (DP LIS)
- POJ 1836 Alignment(DP LIS)
- [POJ 1836]Alignment[DP][LIS]
- POJ 1836 Alignment DP LIS
- poj 2250 Compromise dp求lcs+输出方案
- poj 2975 Nim 尼姆博弈,求取胜方案数
- lightoj1064 【DP求方案】
- hdu 4006__The kth great number(STL)
- P2P平台很赚钱么?
- PHP基础----PHP 会话管理----24操作 Session
- 魔法训练
- 经典排序算法锦集(深度好文)
- POJ 1952 DP LIS求方案数
- Python Format用法
- PHP基础----PHP 与 MySQL----php操作数据库标准思路(自己总结的,没有标号)
- Head First 设计模式
- Xcode 运行程序的时候黑屏的可能原因
- 修改注册表值scancode map来屏蔽键盘上的键
- 2.一个随机生成多种颜色并获取颜色RGB值以及对应十六进制的安卓小应用
- POJ1041 John's trip(欧拉回路 + 并查集 + dfs)
- to-do