sequence2(高精度dp)
2015-11-22 10:51
567 查看
sequence2
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 220 Accepted Submission(s): 90[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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)
[align=left]Output[/align]
For each cases, please output an integer in a line as the answer.
[align=left]Sample Input[/align]
3 2
1 2 2
3 2
1 2 3
[align=left]Sample Output[/align]
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[20],len; void init(int x){ mem(this->num,0); this->num[0]=x; this->len=1; } }; BIGINT operator + (BIGINT a,BIGINT b){ BIGINT c; c.init(0);//c要记得初始化。。。 int len=max(a.len,b.len); for(int i=0;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+1]++; if(c.num[len])len++; }c.len=len; return c; } void print(BIGINT a){ for(int i=a.len-1;i>=0;i--){ printf("%d",a.num[i]); }puts(""); } BIGINT dp[110][110],ans;//以j结尾长度为i的个数 int m[110]; int main(){ int n,k; while(~scanf("%d%d",&n,&k)){ for(int i=1;i<=n;i++)scanf("%d",m+i); mem(dp,0); for(int i=1;i<=n;i++)dp[1][i].init(1); for(int i=1;i<=n;i++) for(int j=1;j<i;j++) if(m[i]>m[j]){ for(int x=2;x<=n;x++){ dp[x][i]=dp[x-1][j]+dp[x][i]; } } ans.init(0); for(int i=1;i<=n;i++)ans=ans+dp[k][i]; print(ans); } return 0; }
大神优化过的代码。。。好难懂。。。还没懂。。。
代码:
#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; }
相关文章推荐
- picasso vs UIL
- Parcel: unable to marshal value {CLASSNAME}
- Arduino与PC串口通信程序中出现的问题
- 编译使用Android源码中的GIF图片工具包--framesequence
- 黑马程序员-GUI图形用户界面
- java webservice服务器端获取request对象的三种方式
- org.hibernate.QueryException: Space is not allowed after parameter prefix ':'
- Ext.QuickTips.init();
- HDU 2767 Proving Equivalences (tarjan scc)
- iOS - UIButton 开发总结
- UiDevice新增API
- HDU 2767 Proving Equivalences(强连通缩点)
- EasyUI常用控件的禁用方法
- request biji
- leetcode笔记:N-Queens II
- Druid监控数据库
- duilib 入门一之界面库基本原理
- 如何解决virtualbox中不能打开一个虚拟任务之uuid不匹配的问题
- 移植opencv到pcDuino
- arduino ide找不到目标文件