省选模拟赛 arg
1 arg (arg.cpp/in/out, 1s, 512MB)
1.1 Description
给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS.
1.2 Input Format
第一行两个整数 n,m.
接下来一行 m 个整数, 表示 A.
1.3 Output Format
一行一个整数表示答案.
1.4 Sample
1.4.1 Input
5 3
1 3 4
1.4.2 Output
11
1.5 Constraints
对于前 30% 的数据, n ≤ 9;
对于前 60% 的数据, n ≤ 12;
对于 100% 的数据, 1 ≤ m ≤ n ≤ 15.
分析:挺难的一道题.
next_permutation+暴力判断可以骗得30分. 阶乘复杂度是肯定不行的,指数复杂度才可以.
那么状压dp?可以参考hdu4352的状压方法. 那还有一维表示什么呢? 我一开始想的是表示前i个数,这样推出来的答案显然是不对的.于是我又想着表示插入了1~i这些数. 错的更离谱了......为什么一定要按顺序插入呢?
正确的状态表示方法应该是f[s][S],s表示所有数的状态(选中or没选中),S表示lis的状态.每次从s中选择一个没有被选中的数转移即可.这样就保证了选的数不会重复.
但是这样复杂度太高了. 而且数组开不下.尝试去优化它. 一个比较明显的结论:S一定是s的子集. 出现在lis中的数在原数列中一定已经出现了.所以可以将状态压成3进制. 第i位为0表示这个数既没有出现在原数列中,也没有出现在lis中,1表示都出现了,2表示没有出现在lis中.这样的话数组就能开下了,时间复杂度O(3^n * n),可以过.
还有一个关键的问题:如何保证A是排列的lis呢? 两个约束条件:
1.ai出现的位置一定在ai+1出现的位置之前.
2.lis的长度正好=m.
对于第一个约束条件,在转移的时候判断一下上一位是否已经出现在lis中即可.
对于第二个约束条件,如果转移后得到的新状态的lis长度>m,则不转移. 因为保证状态中所有的ai都转移到了,当所有的数在排列中都出现时,累加答案即可.
挺好的一道题.没想到状态的正确表示是因为我觉得复杂度太高了,数组也开不下. 有时候想dp题是不能一步到位的.先想一个常规的表示方法,再来优化它是一种很好的分析方法.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll;
int n,m,a[],id[];
ll f[],jie[],ans,zhuangtai[]; int main()
{
scanf("%d%d",&n,&m);
for (int i = ; i <= m; i++)
{
scanf("%d",&a[i]);
id[a[i]] = i;
}
f[] = ;
jie[] = ;
for (int i = ; i <= ; i++)
jie[i] = jie[i - ] * ;
for (int sta = ;sta < jie[n];sta++)
{
if(!f[sta])
continue;
int t = sta;
int num = ,cnt = ;
for (int i = ; i <= n; i++)
{
zhuangtai[i] = t % ;
t /= ;
if (zhuangtai[i])
num++;
if (zhuangtai[i] == )
cnt++;
}
if (num == n)
{
ans += f[sta];
continue;
}
for (int i = ; i <= n; i++)
{
if (zhuangtai[i])
continue;
if (id[i] > && !zhuangtai[a[id[i] - ]])
continue;
int tot = ;
for (int j = ; j < i; j++)
{
if (!zhuangtai[j])
continue;
if (zhuangtai[j] == )
tot++;
}
if (tot == cnt)
{
if (tot == m)
continue;
int nsta = sta + jie[i - ];
f[nsta] += f[sta];
continue;
}
int nsta = sta + jie[i - ];
for (int j = i + ; j <= n; j++)
{
if (zhuangtai[j] == )
{
nsta += jie[j - ];
break;
}
}
f[nsta] += f[sta];
}
}
cout << ans << endl; return ;
}
省选模拟赛 arg的更多相关文章
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- @省选模拟赛03/16 - T3@ 超级树
目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...
- 3.28 省选模拟赛 染色 LCT+线段树
发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...
- 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)
一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...
- NOI2019省选模拟赛 第五场
爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...
- NOI2019省选模拟赛 第六场
传送门 又炸了-- \(A\) 唐时月夜 不知道改了什么东西之后就\(A\)掉了\(.jpg\) 首先,题目保证"如果一片子水域曾经被操作过,那么在之后的施法中,这片子水域也一定会被操作&q ...
- 5.10 省选模拟赛 拍卖 博弈 dp
LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...
- 5.5 省选模拟赛 B Permutation 构造 贪心
LINK:Permutation 对于这种构造神题 我自然是要补的.为啥就我没想出来哇. 30分还是很好写的 注意8!实际上很小 不需要爆搜 写bfs记录状态即可.至于判断状态是否出现与否 可以开ma ...
- 省选模拟赛 4.26 T1 dp 线段树优化dp
LINK:T1 算是一道中档题 考试的时候脑残了 不仅没写优化 连暴力都打挂了. 容易发现一个性质 那就是同一格子不会被两种以上的颜色染.(颜色就三种. 通过这个性质就可以进行dp了.先按照左端点排序 ...
随机推荐
- 136.只出现一次的数字 leetcode ^运算符 JavaScript解法
leetcode上的一道题简单题 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间 ...
- c字符数组里的中文
char *p ="你abc"; strlen(p); //6 utf-8编码中
- Sublime Text 2 - Unable to find git.exe 错误
今日打开 Sublime Text 2,随即弹出 Package Control - Unable to find git.exe 错误.如下, 原因:曾经通过 git clone 命令获取过 Sub ...
- JavaScript/Jquery:Validform 验证表单的相关属性解释
当我们写提交表单的时候往往需要验证表单是否填写了内容,是否正确,这个插件可以很方便的完成我们需要的验证! 使用方法: 1.先引用js <script type="text/javasc ...
- CF刷刷水题找自信 2
CF 1114A Got Any Grapes(葡萄)? 题目意思:给三个人分葡萄,三个人对葡萄的颜色有一些要求,问所准备的三种颜色的葡萄能否满足三人的要求. 解题意思:直接按条件判断即可. #in ...
- Scrum立会报告+燃尽图(十月二十七日总第十八次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2246 项目地址:https://git.coding.net/zhang ...
- 王者荣耀交流协会第三次Scrum立会
会议时间:2017年10月22号 18:00-18:32,时长32分钟. 会议地点:中快餐厅二楼第二排倒数第二个桌子. 立会内容: 1.每位同学汇报了今日工作. 2.通过讨论我们决定用存excel ...
- 从一个app开始学iOS
在大学上了4年学,老师一直给灌输的思想就是,从细微处着手最后看到整体.举个网站的例子.第一个学期老师安排一门课java语言,期末考试就是考试java语言的知识.第二学期java web,第一次课配置j ...
- ranch代码简述
最近要看一下erlang连接池,觉得ranch很不错. github上面有人写了ranch的代码阅读,可以看一下,链接在这里. 1. ranch可以同时监听多个端口,每个端口的连接信息可以单独配置. ...
- Redis的sentinel机制(sentinel节点IP为:192.168.23.10) “哨兵”
万一主节点打击,主从模型将会停止工作,为了解决这个问题,Redis提供了一个sentinel(哨兵),以此来实现主从切换的功能,一旦主节点宕机了,sentinel将会在从节点中挑一个作为主节点.与zo ...