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的更多相关文章

  1. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  2. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  3. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  4. 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)

    一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...

  5. NOI2019省选模拟赛 第五场

    爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...

  6. NOI2019省选模拟赛 第六场

    传送门 又炸了-- \(A\) 唐时月夜 不知道改了什么东西之后就\(A\)掉了\(.jpg\) 首先,题目保证"如果一片子水域曾经被操作过,那么在之后的施法中,这片子水域也一定会被操作&q ...

  7. 5.10 省选模拟赛 拍卖 博弈 dp

    LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...

  8. 5.5 省选模拟赛 B Permutation 构造 贪心

    LINK:Permutation 对于这种构造神题 我自然是要补的.为啥就我没想出来哇. 30分还是很好写的 注意8!实际上很小 不需要爆搜 写bfs记录状态即可.至于判断状态是否出现与否 可以开ma ...

  9. 省选模拟赛 4.26 T1 dp 线段树优化dp

    LINK:T1 算是一道中档题 考试的时候脑残了 不仅没写优化 连暴力都打挂了. 容易发现一个性质 那就是同一格子不会被两种以上的颜色染.(颜色就三种. 通过这个性质就可以进行dp了.先按照左端点排序 ...

随机推荐

  1. cinder创建volume的流程-简单梳理

    1. cinder-api接收到创建的请求,入口:cinder.api.v2.volumes.VolumeController#create,该方法主要负责一些参数的重新封装和校验,然后调用cinde ...

  2. centos7.2 apache开启.htaccess

    打开httpd.conf(在那里? APACHE目录的CONF目录里面),用文本编纂器打开后,查找 (1) AllowOverride None 改为 AllowOverride All (2)去掉下 ...

  3. WeakHashMap介绍

    WeakHashMap简介 WeakHashMap 继承于AbstractMap,实现了Map接口.    和HashMap一样,WeakHashMap 也是一个散列表,它存储的内容也是键值对(key ...

  4. ES6的新特性(17)——Generator 函数的异步应用

    Generator 函数的异步应用 异步编程对 JavaScript 语言太重要.Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可.本章主要介绍 Gener ...

  5. 20181120-6 Beta阶段第2周/共2周 Scrum立会报告+燃尽图 03

    此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2411] 版本控制地址    [https://git.coding.n ...

  6. HDU 5875 Function 优先队列+离线

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5875 Function Time Limit: 7000/3500 MS (Java/Others) ...

  7. ASP.NET Core 中的 Razor 页面介绍

    标题:ASP.NET Core 中的 Razor 页面介绍 地址:https://docs.microsoft.com/zh-cn/aspnet/core/razor-pages/index?view ...

  8. Java中按值传递与按引用传递的区别

    值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响 ...

  9. php addslashes和stripslashes函数

    addslashes — 使用反斜线引用字符串 stripslashes — 反引用一个引用字符串   Example #1 一个 addslashes() 例子 <?php$str = &qu ...

  10. JavaScript与OC的交互-WebViewJavascriptBridge

    WebViewJavascriptBridge实现了在使用UIWebView时JS与ios 的Objective-C nativecode之间的互相调用, 支持的功能有消息发送.接收.消息处理器的注册 ...