zzulioj 1868: UP UP UP! (DP)
2016-04-12 16:15
295 查看
1868: UP UP UP!
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 87 Solved: 23
SubmitStatusWeb
Board
Description
题意很简单,给你长度为n的序列,找出有多少个不同的长度为m的严格上升子序列。(PS:相同子序列的定义为,每一个元素对应的下标都相同)Input
输入数据第一行是个正整数T,表示总共有T组测试数据(T <= 5); 每组数据第一行为n和m,以空格隔开(1 <= n <= 100, 1 <= m <= n); 第二行为n个数,第i个数ai依次代表序列中的每个元素(1<= ai <= 10^9);
Output
对于每组数据,输出一行Case #x: y,x表示当前测试数据的序号(从1开始),y表示结果。 需要注意的是,结果有可能很大,你需要将结果对1000000007(10^9+7)取余。Sample Input
23 2
1 2 3
3 2
3 2 1
Sample Output
Case #1: 3Case #2: 0
//思路:用dp[i][j]表示前i个元素中选出j个单调递增的子序列的个数。
根据题意可以推出动规方程dp[i][j]=dp[i][j]+dp[k][j-1];
具体看代码。
#include<stdio.h> #include<string.h> #include<math.h> #include<set> #include<map> #include<queue> #include<stack> #include<algorithm> #include<iostream> #define INF 0x3f3f3f3f #define ull unsigned long long #define ll long long #define IN __int64 #define N 110 #define M 1000000007 using namespace std; int a ; ll dp ; int main() { int T=1,t,n,m; int i,j,k; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%d",&a[i]); memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { dp[i][1]=1; for(j=1;j<=i;j++) { for(k=1;k<i;k++) { if(a[k]<a[i]) { dp[i][j]=(dp[i][j]+dp[k][j-1])%M; } } } } ll ans=0; for(i=1;i<=n;i++) ans=(ans+dp[i][m])%M; printf("Case #%d: %lld\n",T++,ans); } }
相关文章推荐
- enum类使用理解2
- 第七周项目2-友元类(2)
- Apache Commons工具集简介
- Lvm详解
- 当导航栏滚动到浏览器顶部时,固定导航栏
- 揭秘微信红包:架构、抢红包算法、高并发和降级方案
- Linux ALSA声卡驱动之一:ALSA架构简介
- 横竖屏切换时候Activity的生命周期的总结
- Could not create the view: An unexpected exception was thrown.
- 使用CXF做webservice简单例子
- Matlab从多维正态分布中随机抽取样本:mvnrnd
- 关于mybatis读取数据库字段text类型时,读出数据为地址,并不是字符串的问题
- LinkedList与链表反转
- error while loading shared libraries错误解决办法
- glibc下载地址
- Linux特殊权限:SUID、SGID、SBIT
- 38个学习新技能的最佳网站
- HBase 常用Shell命令
- 常见的排序算法C++实现
- 【lvcreate】创建lv需要在vg上创建