6.25考试整理:江城唱晚&&不老梦&&棠梨煎雪——题解
按照旧例,先安利一下主要作者:一扶苏一 以及扶苏一直挂念的——银临姐姐:银临_百度百科 (滑稽)
好哒,现在步入正题:
先看第一题:



题解:
在NOIP范围内,看到“求方案数”,就说明这个题是一个计数问题。数据范围小的时候一般用DP/递推,数据范围大了的话一般就是数学问题的(组合数学警告)。如果这道题用DP的话,状态即为:dp[i][j]表示第i盆花摆到第j个空的方案数。状态转移方程即为:dp[i][j]=∑dp[i-1][k],k=2*(i-2)+1,...,j-2;时间复杂度为O(n2m)。最终答案即为dp[i]的所有情况再乘上A(m,m)(因为花的顺序也会影响到方案数)。
考虑优化,发现dp[i][j]是由若干个连续的dp[i-1]的和得到,自然想到了前缀和优化,设s[i][j]=dp[i][1]+dp[i][2]+...+dp[i][j],则状态转移方程可以改写为dp[i][j]=s[i-1][j-2]-s[i-1][2*(i-2)],这样就可以用O(1)的复杂度推出来状态了。而s则可在每次dp[i]都算完后推出,时间复杂度O(m),那么整体的时间复杂度即为O(nm)。发现状态的复杂度就是O(nm),显然该DP的复杂度优化下限就是O(nm)(因为复杂度不可能比状态数还少啊),即DP已经优化到尽头了,然而并不足以解出这道题,所以接下来还得考虑一下用数学怎么做了。
我们将m盆花放在n个位置中,还有n-m个空位置,由于m盆花要求互不相邻,所以我们要将这m盆花插到n-m个空位置隔出来的n-m+1个空中(之间的n-m-1个空,还有两边的两个空)。看下图感性理解一下吧(滑稽):



所以最后的答案就是C(n-m+1,m)*A(m,m)=A(n-m+1,m),别忘了计算过程中间及最后要取模。
思路就讲完啦,看标程吧:
#include <stdio.h>
int main() {
freopen("ilove.in", "r", stdin);
freopen("ilove.out", "w", stdout);
int I, love, yin, lin;//???
scanf("%d%d%d%d", &I, &love, &yin, &lin);
love = love - yin + ;
int ans = ;
for (int i = love - yin + ; i <= love; ++i) {
ans = 1ll * ans * i % lin;
}
printf("%d\n", ans);
return ;
}
(看到这么短的代码,再看自己考试时2个小时半低效率半走神地推导DP,呵呵~~)
再看第二题:





题解:注意到扶苏行走的规则是:“当扶苏在点u时,扶苏要么在u的孩子中选择一个没有到达过的点v并行走到v,要么选择回到u的家长节点”,这一规则导致扶苏必须一次性的把一个点的子树全部走完后才能从这个点出去,否则就不能再下到子树中没有走过的点了,导致有点没有放上石子,不和题意。由此就知道应从儿子推向父亲的策略。
同时易知一个省石子的策略是将一个节点的儿子都放上石子后,给这个节点放上石子,然后再把他儿子上的所有石子拿走,去向别的节点放石子。同时还发现,一个节点u的一个儿子v放完石子后可以将这个儿子的儿子们上的石子都拿走,去给这个v的兄弟节点放石子,显然这提醒我们呢,很可能要制定一个合理的贪心顺序去依次处理一个节点的所有儿子。
设每个节点u的答案为ansu,走完节点 u 的所有孩子 v 所需要的总石子数 c u;走完所有孩子后,剩下的石子(也就是cu的减去儿子们总的w)为 ret(rest缩写),当 ret ≥ w u的时候,直接用 ret 放下 要在u 放上的石子,于是在节点 u 的放石子总花费就是 c u ,越小越好;当 ret < w u 的时候,用剩下的石子放在 u 上,然后再额外放上去一些石子,这样做的花费是 w u +∑w v,显然是最小的花费,考虑当 c u 越小 ret 才越小,c u 取最小时显然能取到最优情况。综上,可以尽可能使 c u 减小,来达到最优解。这就是贪心所要达到的目的。
那么问题变成了:
有 x 个商品,购买第 i 个物品需要手里有 ans i 元钱,花费 w i 元。求一个顺序
使得购买所有商品所需要的钱数最少。
这个问题的最最优顺序是按照 ans i -w i 不升序购买,也就是差值越大越要先买。
考虑证明:
设有两个物品 i,j,设 a i =ans i -w i ,a j =ans j -w j 。且 a i >a j 。考虑先买 i 再买 j 的
花费是 max(ans i , w i +ans j ) ----1式,同理先买 j 的花费是 max(ans j , w j +ans i )----2式 。
提出 w,则 1式=w i +max(a i ,ans j ),2式=w j +max(a j ,ans i )=w j +max(a j ,a i +w i )=w j +a i +w i 。
考虑 1 式的 max 如果取前面一项,则 1式=w i +a i <2式,如果取后面一项则 1
=w i +ans j =w i +a j +w j <2,于是无论怎么取,1式恒小于2式,于是先买 i 更优。数学归
纳可得按照 ans i -w i 不升序购买最优。于是按照这个顺序,对儿子排一遍序即可。
见标程:
#include <cstdio>
#include <vector>
#include <algorithm> const int maxn = ; int n;
int MU[maxn], ans[maxn];
std::vector<int>son[maxn];//动态数组 void dfs(const int u);
bool cmp(const int &_a, const int &_b); int main() {
freopen("yin.in", "r", stdin);//文件操作
freopen("yin.out", "w", stdout);
scanf("%d", &n);
for (int i = , x; i <= n; ++i) {
scanf("%d", &x);
son[x].push_back(i);
}
for (int i = ; i <= n; ++i) {
scanf("%d", MU + i);
}
dfs();
for (int i = ; i < n; ++i) {
printf("%d ", ans[i]);
}
printf("%d\n", ans[n]);
return ;
} void dfs(const int u) {
for (auto v : son[u])//等价于for(int v=0;v<son[u];v++)
//注意动态数组下标从0开始
{
dfs(v);//深搜每个儿子
}
std::sort(son[u].begin(), son[u].end(), cmp);
int _ret = ;
for (auto v : son[u]) {
if (_ret >= ans[v]) {
_ret -= ans[v];
} else {
ans[u] += ans[v] - _ret;
_ret = ans[v] - MU[v];
}
}
ans[u] += std::max(, MU[u] - _ret);
} inline bool cmp(const int &_a, const int &_b) {
return (ans[_a] - MU[_a]) > (ans[_b] - MU[_b]);//剩下多的在前面
}
终于到最后一题啦:




题解:因为是要求字符串k去匹配一个区间里的所有字符串,所以可以记录一下一个区间中的字符串每位的情况:是否全为0或全为1。对于问号,既可以把他看作0,也可以把他看作1。我们一位一位从前往后看,设当前k的可行情况有ans种。如果在这个区间里当前第w位既可以全是1又可以全是0(即全是问号),那么ans<<=1(相当与ans*=2。为什么要*2?因为k的第w位有两种情况:0或1,由乘法原理知要*2。)若全是0,则ans不变;若全是1,则ans也不变;若既一定有1又一定有0,显然k是不能匹配他们了,就让ans=0,直接break掉。
见到大数据的区间维护与询问,而且维护的信息不是常规维护的信息,就该想到线段数这一数据结构了。(基本查询贼多的题都是数据结构题 ————by 一扶苏一)对每一位,我们都建一个线段数进行维护,由于最多只需建30个不大的线段数,并不会爆空间。(头一次建这么多线段数,真是有点吓人)时间复杂度O(nq logm)(世界上没有什么事情是开一棵线段树不能解决的。如果有,那就开 30 棵——by 一扶苏 一)(但是开30棵线段树还是会TLE的说)。对于最后一个子任务,还是需要再优化一下。注意到n最大30,可以考虑状压。对每个线段树节点可以维护一个longlong型,long long 共有64个二进制位,每2个二进制位去确定一个字符串位,01代表确定全是0,10代表确定全是1,11代表确定既可以是1又可以是0,00代表都不可以。线段树维护时只要按位与就行,维护完毕后在O(n)扫一遍long long 出答案。时间复杂度O(nq + qlogm),就能AC这个题了。思路这么清楚,想必代码也能打出来了吧。把想法用代码实现出来,正是一个合格的OIer要锻炼的品质哟~。
最后在总结一下考试的小技巧:
有关大样例输出的比较,用肉眼看真是麻烦,有没有能让计算机来告诉我们是否一样的方法?有!只要在相应目录下按shift加鼠标右键,打开命令行,用fc命令对比两个文件就行了。有时fc不靠谱,就要自己写一个比较程序。
不要眼高手低,部分分能拿下来也是很好的。也就是说,对于不同的数据范围,我们可以应用不同的算法来拿分。为了避免重名的麻烦,可以定义若干个命名空间,还方便赋予意义。
最后就是交程序前一定要把注释去掉后再编译一遍,确保加文件后不会有因手残RE等被广大OIer痛恨的问题。
6.25考试整理:江城唱晚&&不老梦&&棠梨煎雪——题解的更多相关文章
- 【6.24校内test】T1 江城唱晚
[题目背景] 墙角那株海棠,是你种下的思念. 生死不能忘,高烛照容颜. 一曲江城唱晚,重忆当年坐灯前, 青衫中绣着你留下的线. ——银临<江城唱晚> [问题描述] 扶苏是个喜欢一边听古风歌 ...
- 模拟赛DAY 2 T1江城唱晚
[题目背景] 墙角那株海棠,是你种下的思念. 生死不能忘,高烛照容颜. 一曲江城唱晚,重忆当年坐灯前, 青衫中绣着你留下的线. ——银临<江城唱晚> [问题描述] 扶苏是个喜欢一边听古风歌 ...
- zay大爷的膜你题 D2T1 江城唱晚
依旧是外链... 这一次网易云爆炸了....所以我决定后面的都用QQ 下面是题面 这道题是一道傻逼题 数学题,我们仔细看一看,首先有m朵花的话,我们就有m!种排列方式(也就是m的全排列), 然后我们假 ...
- 6.20校内考试整理——大美江湖&&腐草为萤&&锦鲤抄题解
先安利一下题目作者:一扶苏一 先看第一题: 这道题就是一道简单的模拟题,只要不管一开始的位置,模拟移动与格子对应的触发事件就行了.话不多说,看代码: #include<iostream> ...
- 【6.24校内test】T2 不老梦
[题目背景] 于万人中万幸得以相逢,刹那间澈净明通. 成为我所向披靡的勇气和惶恐,裂山海,堕苍穹. 爱若执炬迎风,炽烈而哀恸,诸般滋味皆在其中. 韶华宛转吟诵,苍凉的光荣,急景凋年深情难共. ——银临 ...
- 模拟赛DAY 2 T2不老梦
[题目背景] 于万人中万幸得以相逢,刹那间澈净明通. 成为我所向披靡的勇气和惶恐,裂山海,堕苍穹. 爱若执炬迎风,炽烈而哀恸,诸般滋味皆在其中. 韶华宛转吟诵,苍凉的光荣,急景凋年深情难共. ——银临 ...
- 2019.2.25考试T3, 离线+线段树
\(\color{#0066ff}{题解}\) #include<bits/stdc++.h> #define LL long long LL in() { char ch; LL x = ...
- 2016.11.6 night NOIP模拟赛 考试整理
题目+数据:链接:http://pan.baidu.com/s/1hssN8GG 密码:bjw8总结: 总分:300分,仅仅拿了120份. 这次所犯的失误:对于2,3题目,我刚刚看就想到了正确思路,急 ...
- 2016.10.29 NOIP模拟赛 PM 考试整理
300分的题,只得了第三题的100分. 题目+数据:链接:http://pan.baidu.com/s/1o7P4YXs 密码:4how T1:这道题目存在着诸多的问题: 1.开始的序列是无法消除的( ...
随机推荐
- 【Qt开发】设置中心窗口 setCentralWidget
http://blog.csdn.net/qter_wd007/article/details/7028920 Qt程序中的主窗口通常具有一个中心窗口部件.从理论上来讲,任何继承自QWidget的类的 ...
- Java中字母大小写的转换
例:String str = "AbC"; 把字符串所有字母变成小写: System.out.println(str.toLowerCase()); 把字符串所有字母大写: Sys ...
- 【转】mysqldump原理探究
作者:胡儿胡儿 来源:CSDN 原文:https://blog.csdn.net/cug_jiang126com/article/details/49824471 —————————————————— ...
- MySQL数据库的特点和优势
MySQL数据库的特点和优势: 1.MySQL性能卓越.服务稳定,很少出现异常宕机. 2.MySQL开放源代码且无版权制约,自主性及使用成本低. 3.MySQL历史悠久,用户使用活跃,遇到问题可以寻求 ...
- Diango路由映射FBV和CBV
django中请求处理方式有2种:FBV(function base views) 和 CBV(class base views),换言之就是一种用函数处理请求,一种用类处理请求. FBV # url ...
- Paper Reading_ML for system
最近(以及预感接下来的一年)会读很多很多的paper......不如开个帖子记录一下读paper心得 SysML相关的文章很多来源于上学期的8980课.有些和具体field(比如DB/architec ...
- Burp Suite详细使用教程-Intruder模块详3
Burp Suite使用详细教程连载的第三章.0×02 Intruder—内置有效负荷测试使用技巧内置有效负荷测试选择项如下图: 今天的小技巧使用的是 numbers,给大伙科普下:Numbers 数 ...
- es6中class类的全方面理解(一)
传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...
- JAVA中关于日期的最常见的操作
//获取当前系统的时间戳 long times = System.currentTimeMillis(); //创建一个当前日期对象 Date now = new Date(); //基于指定的时间戳 ...
- centOS7 通过nmtui和nmcli图形配置网络服务
一.通过nmtui配置网络参数 Linux系统配置网络参数的方式有很多种,其中最简单最直接的方式就是直接修改网卡配置文件,但这种方式也很容易出错,比如说IPADDR.NETMASK.GATEWAY等参 ...