sequence2

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 220    Accepted Submission(s): 90

Problem Description
Given an integer array bi with a length of n, please tell me how many exactly different increasing subsequences.
P.S. A subsequence bai(1≤i≤k) is an increasing subsequence of sequence bi(1≤i≤n) if and only if 1≤a1<a2<...<ak≤n and ba1<ba2<...<bak. Two sequences ai and bi is exactly different if and only if there exist at least one i and ai≠bi.
 
Input
Several test cases(about 5)
For each cases, first come 2 integers, n,k(1≤n≤100,1≤k≤n)
Then follows n integers ai(0≤ai≤109)
 
Output
For each cases, please output an integer in a line as the answer.
 
Sample Input
3 2
1 2 2
3 2
1 2 3
 
Sample Output
2
3

题解:让求一个数列中长度为k的LIS数列的种数(指的数组下标);所以想到用dp,二维dp,dp[i][j]其中i指的是长度,j指的是以j结束的数;所以可以列出状态转移方程;

dp[x][i]=dp[x-1][j]+dp[x][i];每当if(m[i]>m[j])时 开始从2到n遍历;由于数量太大,所以要用到高精度。。。

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define mem(x,y) memset(x,y,sizeof(x))
typedef long long LL;
struct BIGINT{
int num[],len;
void init(int x){
mem(this->num,);
this->num[]=x;
this->len=;
}
};
BIGINT operator + (BIGINT a,BIGINT b){
BIGINT c;
c.init();//c要记得初始化。。。
int len=max(a.len,b.len);
for(int i=;i<len;i++){
c.num[i]=a.num[i]+b.num[i]+c.num[i];
if(c.num[i]>1e8)c.num[i]-=1e8,c.num[i+]++;
if(c.num[len])len++;
}c.len=len;
return c;
}
void print(BIGINT a){
for(int i=a.len-;i>=;i--){
printf("%d",a.num[i]);
}puts("");
}
BIGINT dp[][],ans;//以j结尾长度为i的个数
int m[];
int main(){
int n,k;
while(~scanf("%d%d",&n,&k)){
for(int i=;i<=n;i++)scanf("%d",m+i);
mem(dp,);
for(int i=;i<=n;i++)dp[][i].init();
for(int i=;i<=n;i++)
for(int j=;j<i;j++)
if(m[i]>m[j]){
for(int x=;x<=n;x++){
dp[x][i]=dp[x-][j]+dp[x][i];
}
}
ans.init();
for(int i=;i<=n;i++)ans=ans+dp[k][i];
print(ans);
}
return ;
}

大神优化过的代码。。。好难懂。。。还没懂。。。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ull unsigned long long
#define ll long long
#define N 100005
#define BASE 13131
int n,k;
int a[105];
struct Cbig
{
int num[20],len;
void init(int x)
{
len=1;
num[0]=x;
}
}dp[2][105],ans,c;
Cbig add(Cbig &a,Cbig &b)
{
c.len=max(a.len,b.len);
c.num[0]=0;
for(int i=0;i<c.len;i++)
{
c.num[i+1]=0;
if(i<a.len) c.num[i]+=a.num[i];
if(i<b.len) c.num[i]+=b.num[i];
if(c.num[i]>=100000000)
{
c.num[i]-=100000000;
c.num[i+1]=1;
}
}
if(c.num[c.len]) c.len++;
return c;
}
void print(Cbig &a)
{
printf("%d",c.num[a.len-1]);
for(int i=a.len-2;i>=0;i--)
printf("%08d",a.num[i]);
puts("");
}
int main()
{
//freopen("tt.in", "r", stdin);
while(cin>>n>>k)
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
dp[0][0].init(1);
for(int i=1;i<=n;i++) dp[0][i].init(0);
int p=0,q=1;
for(int t=1;t<=k;t++)
{
p^=1;q^=1;
for(int i=0;i<=n;i++) dp[p][i].init(0);
for(int i=1;i<=n;i++)
{
for(int j=0;j<i;j++)
if(j==0||a[j]<a[i])
dp[p][i]=add(dp[p][i],dp[q][j]);
}
}
ans.init(0);
for(int i=1;i<=n;i++)
ans=add(ans,dp[p][i]);
print(ans);
}
return 0;
}

  

sequence2(高精度dp)的更多相关文章

  1. Hdu 5568 sequence2 高精度 dp

    sequence2 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=556 ...

  2. uva 10069 Distinct Subsequences(高精度 + DP求解子串个数)

    题目连接:10069 - Distinct Subsequences 题目大意:给出两个字符串x (lenth < 10000), z (lenth < 100), 求在x中有多少个z. ...

  3. POJ 1625 Censored!(AC自动机+高精度+dp)

    http://poj.org/problem?id=1625 题意: 给出一些单词,求长度为m的串不包含这些单词的个数. 思路: 这道题和HDU 2243和POJ 2778是一样的,不同的是这道题不取 ...

  4. 【Luogu】P1005矩阵取数游戏(高精度+DP)

    题目链接 yeah终于过辣! DP,f[i][j]表示每行还剩i到j这个区间的数没取的时候的值.借这个题我也把高精度的短板弥补了一下,以后高精加高精乘应该是没问题了. 哇终于不怂高精了…… 放上代码. ...

  5. POJ 1737 Connected Graph(高精度+DP递推)

    题面 \(solution:\) 首先做个推销:带负数的压位高精度(加减乘+读写) 然后:由 \(N\) 个节点组成的无向图的总数为: \(2^{N*(N-1)/2}\) (也就是说这个图总共有 \( ...

  6. POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)

    题目链接:Censored! 解析:AC自己主动机 + 高精度 + 简单DP. 字符有可能会超过128.用map映射一下就可以. 中间的数太大.得上高精度. 用矩阵高速幂会超时,简单的DP就能解决时间 ...

  7. HDU 5568:sequence2 大数+DP

    sequence2  Accepts: 93  Submissions: 358  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 6553 ...

  8. TYVJ 矩阵取数 Label:高精度+dp

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...

  9. HDU 5568 sequence2 区间dp+大数

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5568 题意: 求所有长度为k的严格升序子序列的个数. 题解: 令dp[i][k]表示以i结尾的长度为 ...

随机推荐

  1. HDU 1848 Fibonacci again and again

    题解:尼姆博弈,对于1至1000计算SG函数,每次取最小的前继值,SG值异或为0则为P-position. #include <cstdio> #include <cstring&g ...

  2. HDOJ 1253 胜利大逃亡(bfs)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1253 思路分析:因为问题需要寻找到达终点的最短的距离(最短的步数),即在状态转换图上需要找出层次最浅的 ...

  3. 如何提取出ppt中的文字?

    最近在看一位老师的教学视频,视频里大部分的知识都记录在ppt里,于是很想将ppt中的文字提取出来,如果我一页一页地粘贴复制的话,效率低到吓人,因为一章的ppt有130多页,于是在网上搜索了一下方法,与 ...

  4. 使用Lock实现信号量

    public class SemaphoreOnLock {     private final Lock lock = new ReentrantLock();         private fi ...

  5. GDI+入门——带你走进Windows图形的世界

    一.GDI+基础 1.GDI+简单介绍 GDI+是微软的新一代二维图形系统,它全然面向对象,要在Windows窗口中显示字体或绘制图形必需要使用GDI+.GDI+提供了多种画笔.画刷.图像等图形对象, ...

  6. STL之string插入

    #include <iostream> #include <string> using namespace std; int main() { string s("h ...

  7. Stack集合、queue集合、hashtable集合

    1.栈:Stack,先进后出,一个一个赋值,一个一个取值,按顺序. .count           取集合内元素的个数 .push()         将元素一个一个推入集合中//stack集合存入 ...

  8. 关于RadUpload上传问题总结

    最近在开发上传控件,使用RadUpload上传大附件 发现了几个小问题,总结后分享给大家: 1.IE6浏览器下文件的路径显示的是物理路径,需要进行转换 2.IIS7.0 配置时要选择经典模式 3.we ...

  9. 在一个数组中是否存在两个数A、B的和为M

    #include <iostream>#include <algorithm>//#include <vector>using namespace std; int ...

  10. 说说读卡应用那点事儿,以SCL010为例

    前一阵子的项目, 跟读卡应用有关,这篇博客算是我学习智能卡方面知识的而一个总结,也可以看作这个领域的一个很简单的简介,他写得很不书面,更像是沿着我自己认识过程的总结.所以这里面有很多我自己理解的地方, ...