hihocoder 1609 数组分拆II
来源:互联网 发布:php无限极分类 编辑:程序博客网 时间:2024/05/22 16:50
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定一个包含N个整数的数组A=[A1, A2, ... AN]。小Ho想将A拆分成若干连续的子数组,使得每个子数组中的整数都是两两不同的。
在满足以上条件的前提下,小Ho想知道子数组数量最少是多少。
同时他还想知道,在数量最少的前提下有多少中不同的拆法。
例如对于[1, 2, 3, 1, 2, 1],最少需要3个子数组。有5种不同的拆法:
[1], [2, 3, 1], [2, 1]
[1, 2], [3, 1], [2, 1]
[1, 2], [3, 1, 2], [1]
[1, 2, 3], [1], [2, 1]
[1, 2, 3], [1, 2], [1]
输入
第一行包含一个整数N。
第二行包含N个整数A1, A2, ... AN。
对于30%的数据,满足1 ≤ N ≤ 10
对于60%的数据,满足1 ≤ N ≤ 1000
对于100%的数据,满足1 ≤ N ≤ 100000, 1 ≤ Ai ≤ 100000
输出
输出两个整数。第一个表示子数组最少的数量,第二个表示在数量最少的前提下有多少种拆法。
由于拆法可能非常多,你只需要输出答案除以1000000007的余数。
样例输入
6
1 2 3 1 2 1
样例输出
3 5
分析:从左往右扫描, 找出最少的分组情况,然后DP 设 d[i] 为 (以最少分组情况考虑 )1~i 能有几种分法。d[i] = Sum(d[j] 满足条件的j).
#include<iostream>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>const int maxn = 1000000;const int inf = 1e9;const long long int mod = 1000000007;typedef long long ll;using namespace std;int n,a[maxn+5],L[maxn+5],R[maxn+5],last[maxn+5];int l[maxn+5],r[maxn+5],cnt;ll d[maxn+5];int main(){ int MaxL,s,t; ll cot; while(~scanf("%d",&n)) { for(int i=1; i<=n; i++) scanf("%d",&a[i]); memset(last,-1,sizeof(last));//找出每一个数 上一次出现的 下标L[i] for(int i=1; i<=n; i++) L[i] = last[a[i]], last[a[i]] = i; memset(last,-1,sizeof(last));// 找出每一个数 下一次出现的 下标R[i] for(int i=n; i; i--) R[i] = last[a[i]],last[a[i]] = i; for(int i=1; i<=n; i++) if(R[i]<0) R[i] = n+1; cnt = 0, s = 1, t = 1,MaxL = n+2; for(int i=1; i<=n+1; i++)// 找出最少的分组。 以最少分组的情况考虑。有一些数是必须组合在一起的,设哪些区间为l[i],r[i] { if(i==MaxL) { l[++cnt] = s, r[cnt] = max(t,s) ,s=t=i , MaxL=R[i]; } else { if(MaxL>R[i]) t = i,MaxL = R[i]; } } memset(d,0,sizeof(d)); r[cnt] = n; d[0] = 1, l[cnt+1] = r[cnt+1] = n+1;// d[i]表示 1~i 以最少分组的情况考虑 能有分几出种。 for(int i=1; i<=cnt; i++)//(l[i-1],r[i-1]) x1 x2 x3... (l[i],r[i]) y1 y2 y3 ... (l[i+1],r[i+1])./ d[yi] = sum(d[xj] 满足条件的). { s = r[i-1], cot = 0, MaxL = -1; for(int j=l[i];j<=r[i];j++) s = max(s,L[j]);//在 (l[i],r[i])中找出 开始的 最左符合边界。 for(int j=s; j<l[i]; j++) cot = (cot + d[j])%mod; for(int j=r[i]; j<l[i+1]; j++) { MaxL = max(MaxL,L[j]);// 随着 j 的右移 最左符合边界 或者不变或者上升 不会下降的。 while(s<MaxL&&s<l[i]) cot = (cot - d[s]+mod)%mod, s++; d[j] = cot; } } printf("%d %lld\n",cnt,d[n]); } return 0;}/*72 2 5 4 4 3 34 1142 4 1 5 6 7 8 1 9 10 11 12 1 133 251411 11 11 13 2 3 5 2 1 12 8 7 5 114 1*/
阅读全文
0 0
- hihocoder 1609 数组分拆II
- #1475 : 数组分拆
- hihoCoder 1261 String Problem II
- hihocoder#1482-出勤记录II
- hihocoder #1519 逃离迷宫II
- hihocoder #1519 : 逃离迷宫II
- hihocoder 1519 : 逃离迷宫II
- [hihoCoder]#1615 : 矩阵游戏II
- [HihoCoder]#1359 : 震荡数组
- Hihocoder 数组重排
- hihocoder 数组重排
- 分拆数组技巧应用
- hihoCoder挑战赛17 B String Problem II hihoCoder 1261
- HihoCoder]#1376 : 数组去重
- HihoCoder 1336 二维树状数组
- hihoCoder 1523 : 数组重排2
- hihocoder 1523 : 数组重排2
- hihoCoder 1523 : 数组重排2
- codeforces Round #441 div2
- http请求与响应,TCP三次握手&四次分手
- spring boot 集成 mybatis
- 一周第四次课 2017.10.19 单用户模式、救援模式、克隆虚拟机、Linux机器相互登录
- Eclipse中的jsp文件中不能按住Ctrl点击变量定位到定义位置或者第一次引用位置
- hihocoder 1609 数组分拆II
- SlidingMenu的使用 左右滑出(挤出)布局
- ue4 如何修改打包android app的icon和欢迎界面
- php题目使用3中以上方法获取文件扩展名
- HDU
- 关于数据请求安全性问题
- 热水锅炉控制系统 分时段控制水温和水位
- 漫步最优化二十五——斐波那契搜索
- javascript 添加表单脚本 利用了bootstrap 框架美化