[HDU 5568] sequence2 dp+大数
发布时间:2020-12-14 02:12:38 所属栏目:大数据 来源:网络整理
导读:http://acm.hdu.edu.cn/showproblem.php?pid=5568 题意:给定长度为 n 的序列 bi??,求有多少长度为 k 的但是本质不同的上升子序列。本质不同的意思就是两个子序列中至少有一个位置的下标不同。 思路:dp, dp[i][j] 表示已经选了 i 个数做子序列前驱是 j 。
http://acm.hdu.edu.cn/showproblem.php?pid=5568 题意:给定长度为 n 的序列 bi??,求有多少长度为 k 的但是本质不同的上升子序列。本质不同的意思就是两个子序列中至少有一个位置的下标不同。 思路:dp, dp[i][j] 表示已经选了 i 个数做子序列前驱是 j 。 dp[i][j] = sum( dp[i + 1][l]) ( l > j,ary[l] > ary[j])。 代码: #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct BigInteger //大数类
{
int len;
int arg[105];
BigInteger(int x = 0){
IntToBigInteger(x);
}
void IntToBigInteger(int x)
{
len = 0;
memset(arg, 0,sizeof(arg));
do{
arg[len++] = x % 10;
x = x / 10;
}while (x);
}
friend ostream& operator<<(ostream &out,BigInteger w)
{
for (int i = w.len - 1; i >= 0; i--){
out<<w.arg[i];
}
return out;
}
friend BigInteger operator+(BigInteger r,BigInteger w)
{
int len = r.len > w.len ? r.len : w.len;
for (int i = 0; i < len; i++){
if(i < w.len)
r.arg[i] = r.arg[i] + w.arg[i];
r.arg[i + 1] += r.arg[i] / 10;
r.arg[i] = r.arg[i] % 10;
}
while (r.arg[len] >= 10){
r.arg[len + 1] += r.arg[len] / 10;
r.arg[len] = r.arg[len] % 10;
len++;
}
if(r.arg[len]) len++;
r.len = len > r.len ? len : r.len;
return r;
}
};
int n,m;
int ary[105];
BigInteger dp[105][105];
BigInteger Dfs(int deep,int pos,int pre) //deep,选了多少个做子序列,pos,搜索到那个下标,pre 前驱
{
if(deep == m - 1)
return 1;
if(pos == n)
return 0;
if(dp[deep][pre].len != -1)
return dp[deep][pre];
BigInteger res = 0;
for(int i = pos + 1; i < n; i++){
if(ary[pre] < ary[i])
res = res + Dfs(deep + 1,i,i);
}
dp[deep][pre] = res;
return dp[deep][pre];
}
int main()
{
while(~scanf("%d%d",&n,&m)){
for(int i = 0; i < n; i++){
scanf("%d",&ary[i]);
}
BigInteger res = 0;
for(int i = 0; i < 105; i++){
for(int k = 0; k < 105; k++){
dp[i][k].len = -1;
}
}
for(int i = 0; i < n; i++){
res = res + Dfs(0,i);
}
cout<<res<<endl;
}
return 0;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |