NOIP2018提高组金牌训练营——动态规划专题
NOIP2018提高组金牌训练营——动态规划专题
https://www.51nod.com/Live/LiveDescription.html#!#liveId=19
多重背包
二进制优化转化成01背包就好了
一只猪走进了一个森林。很凑巧的是,这个森林的形状是长方形的,有n行,m列组成。我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m。处于第r行第c列的格子用(r,c)表示。
刚开始的时候猪站在(1,1),他的目标是走到(n,m)。由于猪回家心切,他在(r,c)的时候,只会往(r+1,c)或(r,c+1)走。他不能走出这个森林。
这只猪所在的森林是一个非同寻常的森林。有一些格子看起来非常相似,而有一些相差非常巨大。猪在行走的过程中喜欢拍下他经过的每一个格子的照片。一条路径被认为是漂亮的当且仅当拍下来的照片序列顺着看和反着看是一样的。也就是说,猪经过的路径要构成一个回文。
数一数从(1,1)到(n,m)有多少条漂亮路径。答案可能非常巨大,请输出对 $10^9+7$ 取余后的结果。
样例解释:有三种可能
收起
输入
单组测试数据。
第一行有两个整数 n,m (1≤n,m≤500),表示森林的长和宽。
接下来有n行,每行有m个小写字母,表示每一个格子的类型。同一种类型用同一个字母表示,不同的类型用不同的字母表示。
输出
输出答案占一行。
输入样例
3 4
aaab
baaa
abba
输出样例
3
注意到500分数据范围,考虑n三方的算法
发现回文非常难判断,可能要记录整个路径,不现实
所以从两端开始搜
f[x1][y1][x2][y2]表示从(1, 1)到(x1,y1),从(n, m)走到(x2, y2)
的方案数。这样就很好转移了,有四个方程,分别对应从(1, 1)往下还是往右
(n, m)往上还是往左
但是发现这样会炸空间,炸时间
那么显然有x1 + y1 = x2 + y2
那么f[x1][y1][x2]可以省去一维
但这样会炸空间
怎么办?
可以这样设计f[step][x1][x2], step = x1 + y1
有什么区别?
这样的话step的这一维只和step-1有关
所以可以用滚动数组优化掉一维的空间。
那么这道题就完美的解决了。
代码略……
1412 AVL树的种类
https://www.51nod.com/Challenge/Problem.html#!#problemId=1412&judgeId=0
输入
一行,包含一个整数n。 (0 < n <= 2000)
输出
一行表示结果,由于结果巨大,输出它对1000000007取余数的结果。
输入样例
10
输出样例
60
显然状态和节点数和高度有关,
设f[n][d]为有n个节点,高度为d的方案数
那么对于高度d,考虑左右子树,只存在与d-1与d-2两种情况
对于节点数n,可以枚举左右子树分别有多少,有i和n-i-1两种情况
那么转移的方程用到了乘法原理
dp[i][d]= dp[i - j - 1][d - 1] * dp[j][d - 1] + dp[i - j - 1][d - 1] * dp[j][d - 2] + dp[i - j - 1][d - 2] * dp[j][d - 1]
然后注意一些细节,见代码
#include<bits/stdc++.h>
#define add(a, b) a = (a + b) % MOD
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; typedef long long ll;
const int MAXN = 2e3 + ;
const int MAXM = ;
const int MOD = ;
ll dp[MAXN][MAXM + ];
int n; int main()
{
scanf("%d", &n);
dp[][] = dp[][] = ; //注意这个初始化,特别注意空的节点
_for(i, , n)
_for(d, , MAXM) //深度最大也就十几左右
REP(j, , i) //最少0个,最多i-1个
{
add(dp[i][d], dp[i - j - ][d - ] * dp[j][d - ] % MOD);
add(dp[i][d], dp[i - j - ][d - ] * dp[j][d - ] % MOD);
add(dp[i][d], dp[i - j - ][d - ] * dp[j][d - ] % MOD);
} ll ans = ;
_for(d, , MAXM)
add(ans, dp[n][d]);
printf("%lld\n", ans); return ;
}
输入
第一行两个数n,m(n<=20,m<=100)。
接下来m行,每行一个数ai,表示第ai道题目可能会有i这个分数的档次。
输出
一个数表示最多逆序对个数。
输入样例
5 7
1
2
3
4
1
2
5
输出样例
4
n<=20
反应到状压dp
一般来说,逆序对是按照位置的顺序来求的
但是这道题要逆向思维,按照大小来求
因为题目输入的权值是递增的
所以只要判断在当前位置的后面有多少位置即可
但是这里要注意一点,我一开始用填表法去做,会WA
因为这里状态转移的时候涉及状态本身中1的个数,而有些状态是不合法的。
以前很多题可以用填表法是因为更新状态的时候用到的是状态中的某个位置,然后由位置导出权值,这样即使位置不合法,
导出权值的时候也会不合法而不会导致错解。但这道题就是用到状态本身,使得不合法的状态会导致错解
填表法就会把这些状态算进来。或者加个判断,判断之前的状态要是合法的,但是这显然没有刷表法方便
如果用到刷表法的话,就要注意初始化,起始状态初始化为0,其他为-1,表示不合法
然后转移的时候要判断当前状态合不合法
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; int dp[( << ) + ], n, m; int main()
{
memset(dp, -, sizeof(dp));
dp[] = ;
scanf("%d%d", &n, &m);
_for(k, , m)
{
int x; scanf("%d", &x); x--;
REP(S, , << n)
if(dp[S] >= && !(S & ( << x)))
{
int sum = ;
REP(j, x + , n)
if(S & ( << j))
sum++;
dp[S | ( << x)] = max(dp[S | ( << x)], dp[S] + sum);
}
}
printf("%d\n", dp[( << n) - ]);
return ;
}
NOIP2018提高组金牌训练营——动态规划专题的更多相关文章
- NOIP2018提高组金牌训练营——搜索专题
NOIP2018提高组金牌训练营——搜索专题 1416 两点 福克斯在玩一款手机解迷游戏,这个游戏叫做”两点”.基础级别的时候是在一个n×m单元上玩的.像这样: 每一个单元有包含一个有色点.我们将用不 ...
- NOIP2018提高组金牌训练营——字符串专题
NOIP2018提高组金牌训练营——字符串专题 1154 回文串划分 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式. a|bb|aabaa - 3 个 ...
- NOIP2018提高组金牌训练营——数论专题
地址 https://www.51nod.com/live/liveDescription.html#!liveId=23 1187 寻找分数 给出 a,b,c,d, 找一个分数p/q,使得a/b & ...
- [NOIp2018提高组]旅行
[NOIp2018提高组]旅行: 题目大意: 一个\(n(n\le5000)\)个点,\(m(m\le n)\)条边的连通图.可以从任意一个点出发,前往任意一个相邻的未访问的结点,或沿着第一次来这个点 ...
- [NOIp2018提高组]赛道修建
[NOIp2018提高组]赛道修建 题目大意: 给你一棵\(n(n\le5\times10^4)\)个结点的树,从中找出\(m\)个没有公共边的路径,使得第\(m\)长的路径最长.问第\(m\)长的路 ...
- [NOIp2018提高组]货币系统
[NOIp2018提高组]货币系统 题目大意: 有\(n(n\le100)\)种不同的货币,每种货币的面额为\([1,25000]\)之间的一个整数.若两种货币系统能够组合出来的数是相同的的,那我们就 ...
- [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路
[NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路 题目大意: 对于长度为\(n(n\le10^5)\)的非负数列\(A\),每次可以选取一个区间\(-1\).问将数列清零至少需要 ...
- NOIP2018提高组省一冲奖班模测训练(六)
NOIP2018提高组省一冲奖班模测训练(六) https://www.51nod.com/Contest/ContestDescription.html#!#contestId=80 20分钟AC掉 ...
- NOIP2018提高组省一冲奖班模测训练(五)
NOIP2018提高组省一冲奖班模测训练(五) http://www.51nod.com/Contest/ContestDescription.html#!#contestId=79 今天有点浪…… ...
随机推荐
- swift 笔记 (十四) —— 构造过程
构造过程 为了生成类.结构体.枚举等的实例,而做的准备过程,叫做构造过程. 为了这个过程,我们一般会定义一个方法来完毕,这种方法叫做构造器.当然它的逆过程,叫做析构器,用于在实例被释放前做一些清理工作 ...
- 错误: su: 无法设置组: 不允许的操作
到 /bin目录下,用ls -l 看下su文件的权限是不是rwxr-xr-x或者-rwxrwxrwx 执行这条命令chmod ug+s su
- 国外物联网平台初探(四):Ayla Networks
定位 Ayla企业软件解决方案为全球部署互联产品提供强大的工具 功能 Ayla的IoT平台包含3个主要组成部分: (1) Ayla嵌入式代理Ayla Embedded Agents (2) Ayla云 ...
- UVa 11722(几何概率)
题意:你和你的朋友要乘坐火车,并且都会在A城市相遇,你会在(t1,t2)中的任意时刻以相同的概率密度到达, 你朋友会在(s1,s2)中的任意时刻以相同的概率密度到达,你们的火车在A城市都会停留w分钟, ...
- php如何将网上的图片下载到本地
<?phpheader("Content-Type: application/force-download");header("Content-Dispositio ...
- linux系统在线搭建禅道
1.先安装wget:yum -y install wget 2.下载安装禅道:[root@zhaowen ~]# wget http://dl.cnezsoft.com/zentao/9.0.1/Ze ...
- shp系列(七)——利用C++进行Shx文件的写(创建)
之前介绍了Shp文件和Dbf的写(创建),最后来介绍一下Shx文件的写(创建).Shx文件是三者之中最简单的一个,原因有两个:第一是Shx文件的头文件与Shp文件的头文件几乎一样(除了FileLeng ...
- Codeforces Round #198 (Div. 2)A,B题解
Codeforces Round #198 (Div. 2) 昨天看到奋斗群的群赛,好奇的去做了一下, 大概花了3个小时Ak,我大概可以退役了吧 那下面来稍微总结一下 A. The Wall Iahu ...
- 微软抛弃微软.Net了吗?Net技术的未来在哪里-浅谈微软技术路线
winform:优点是简单易学,缺点是界面做不好看,界面适应能力很差. wpf:微软结合了显卡渲染技术推出的界面设计方式,模仿html推出了自己的xaml,winform能实现的wpf都能实现,因为w ...
- 搭建eclipse的安卓开发环境(eclipse+jdk+adt+sdk)
学校暑期大作业让用安卓写一个app,有两种方案(android stduio+sdk和eclipse+jdk+adt+sdk)折腾了几天发现还是后者好用,但是安装环境和下载真的是去了半条命,(不过由于 ...