sequence2
Accepts: 93
Submissions: 358
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
给定长度为n的序列bi,求有多少长度为k的本质不同的上升子序列。 设该序列位置为a1,a2...ak一个序列为上升子序列,当且仅当a1<a2<...<ak且ba1<ba2<...<bak。 本质不同当且仅当两个序列a和A存在一个i使得ai≠Ai。
输入描述
若干组数据(大概5组)。 每组数据第一行两个整数n(1≤n≤100),k(1≤k≤n)。 接下来一行n个整数bi(0≤bi≤109)。
输出描述
对于每组的每个询问,输出一行。
输入样例
3 2 1 2 2 3 2 1 2 3
输出样例
2 3
很久没写dp了
推了好久的状态转移方程都没有推出来
c(100, 50)肯定会暴long long ,所以需要高精度
所以我就马上想到了java中的大数
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main
{
public static void main(String args[])
{
Scanner cin = new Scanner(System.in);
while(cin.hasNext())
{
int n = cin.nextInt();
int k = cin.nextInt();
int a[] = new int[222];
int i, j, kk;
for(i = 1; i <= n; i++) a[i] = cin.nextInt();
BigInteger [][]dp = new BigInteger[k*2][];
for(i = 0; i < 2*k; i++)
dp[i] = new BigInteger[2*n];
BigInteger ans = BigInteger.ZERO;
for(i = 0; i <= k; i++)
{
for(j = 0; j <= n; j++)
dp[i][j] = BigInteger.ZERO;
}
for(j = 1; j <= n; j++) dp[1][j] = BigInteger.ONE;
for(i = 2; i <= k; i++)
{
for(j = 1; j <= n; j++)
{
for(kk = j+1; kk <= n; kk++)
{
if(a[kk] > a[j])
dp[i][kk] = dp[i][kk].add( dp[i-1][j] );
}
}
}
for(i = 1; i <= n; ++i)
ans = ans.add(dp[k][i]);
System.out.println(ans);
}
}
}