子序列的个数(解)--【英雄会】
2014-01-07 23:39
281 查看
本题同样来自caopengcs,只要你有兴趣,每个人都可以出题(出题入口在主页右侧边栏“贡献题目”->“我要发布”内),以下是题目详情:
子序列的定义:对于一个序列a=a[1],a[2],......a
,则非空序列a'=a[p1],a[p2]......a[pm]为a的一个子序列,其中1<=p1<p2<.....<pm<=n。
例如:4,14,2,3和14,1,2,3都为4,13,14,1,2,3的子序列。 对于给出序列a,有些子序列可能是相同的,这里只算做1个,要求输出a的不同子序列的数量。
输入: 长度为n的数组1<=n<=100,数组元素0<=a[i]<=110
输出:子序列 的个数对1000000007取余数的结果(由于答案比较大,输出Mod 1000000007的结果即可)。
首先感谢cp大神,在这一题上有着巨大的帮助,因为之前理解题意的原因,一直认为测试点有问题,后来茅塞顿开,终于理解了题意;
题目中的实例有一定的特殊性,假如给的序列为{1, 1, 4, 1};
则其子序列有“1”,“4”,“1, 1”,“1, 4”,"4, 1","1, 1, 4",“1, 1, 1”,“1, 4, 1”,以及"1, 1, 4, 1"共九种;
如果这个序列没有重复数据的话,很明显这就是一个集合的问题了;
不过当出现重复的话,此时的解法就不一样了:
如果未发生重复现象,则子序列的个数随着个数的增加,其个数sum[i] = sum[i - 1] + dp[i];此时dp[i] = sum[i - 1];
若之前发生的重复现象,即exist[x] != 0;此时的dp[i]就会发生与之前出现x值重复的组合,此时dp[i] = sum[i - 1];
dp[i] -= sum[exist[x] - 1];
继续深究,贴个代码:
多多交流...o(∩_∩)o
子序列的定义:对于一个序列a=a[1],a[2],......a
,则非空序列a'=a[p1],a[p2]......a[pm]为a的一个子序列,其中1<=p1<p2<.....<pm<=n。
例如:4,14,2,3和14,1,2,3都为4,13,14,1,2,3的子序列。 对于给出序列a,有些子序列可能是相同的,这里只算做1个,要求输出a的不同子序列的数量。
输入: 长度为n的数组1<=n<=100,数组元素0<=a[i]<=110
输出:子序列 的个数对1000000007取余数的结果(由于答案比较大,输出Mod 1000000007的结果即可)。
首先感谢cp大神,在这一题上有着巨大的帮助,因为之前理解题意的原因,一直认为测试点有问题,后来茅塞顿开,终于理解了题意;
题目中的实例有一定的特殊性,假如给的序列为{1, 1, 4, 1};
则其子序列有“1”,“4”,“1, 1”,“1, 4”,"4, 1","1, 1, 4",“1, 1, 1”,“1, 4, 1”,以及"1, 1, 4, 1"共九种;
如果这个序列没有重复数据的话,很明显这就是一个集合的问题了;
不过当出现重复的话,此时的解法就不一样了:
如果未发生重复现象,则子序列的个数随着个数的增加,其个数sum[i] = sum[i - 1] + dp[i];此时dp[i] = sum[i - 1];
若之前发生的重复现象,即exist[x] != 0;此时的dp[i]就会发生与之前出现x值重复的组合,此时dp[i] = sum[i - 1];
dp[i] -= sum[exist[x] - 1];
继续深究,贴个代码:
#include <cstdio> #include <string> #include <cstring> #include <iostream> const int M = 1000000007; using namespace std; int run(const int *a, int n) { int exist[111] = {0}; //判断是否存在,数组元素0<=a[i]<=110 int dp[101] = {0}; int sum[101] = {1}; //个数 int x; for (int i = 1; i <= n; ++i) { x = a[i - 1]; //一个一个读取元素 dp[i] = sum[i - 1]; // if (exist[x] != 0 ) { dp[i] -= sum[exist[x] - 1]; //之前出过此值,出现重复 if(dp[i] < 0) dp[i] += M; } exist[x] = i; //记录最近出现x的下标 sum[i] = sum[i - 1] + dp[i]; //更新子序列个数 if (sum[i] >= M) //超限则进行-M,重新在表示范围内 { sum[i] -= M; } } if (--sum < 0) //-1 { sum += M; } return sum ; } //start 提示:自动阅卷起始唯一标识,请勿删除或增加。 int main() { int a[] = {1, 1, 4, 1}; int length = sizeof(a) / sizeof(int); cout<<run(a, length); return 0; } //end //提示:自动阅卷结束唯一标识,请勿删除或增加。
多多交流...o(∩_∩)o
相关文章推荐
- 寒假计划
- 随机验证码---支持大小写字母、数字、随机字体、文字大小(三)
- intent1
- 希腊人4
- 传智学习日志篇:四
- intent
- A*算法简介
- uCOSII在BC45的仿真
- 操作系统课堂笔记(5)存储管理
- Sublime Text使用技巧
- java 依次单条数据 写入数据库 500万条
- AbsoluteLayout
- 配置zendframework开始工作(加入环境变量)
- 进程_查看堆大小,句柄,进程数限制
- XZ压缩最新压缩率之王
- 妙味——图片自动播放切换
- XenServer6.2虚拟化实战安装步骤
- !!!Chapter 5 The Network Layer
- FrameLayout
- EF扩展库(批量操作)