cstring

牛客网 暑期ACM多校训练营(第二场)D.money-贪心 or 动态规划

守給你的承諾、 提交于 2021-01-21 04:59:40
D. money 贪心,直接贴官方的题解吧。 题目大意 你要按照顺序依次经过n个商店,每到达一个商店你可以购买一件商品,也可以出售你手中的商品。 同一时刻你手上最多拿一件商品。在第i个商店购买和出售的代价都是a[i]。 问你经过完n个商店后的最大收益。 同时,在最大化收益的前提下,求最小的交易次数。 做法 DP f[i][0/1]表示已经访问完了i个商店,你手中是否有商品,此时的最大收益。 g[i][0/1]表示当f[i][j]取最大值时最少的交易次数。 贪心 首先,如果a[i]=a[i+1],则可以删掉第i+1个商店。因为任何在第i+1个商店进行的交易都可以转为在第i个商店 进行,且收益不变。之后,如果a[i]<a[i+1],则离开第i个商店时一定要带上一件商品。如果a[i]>a[i+1],则离开 第i个商店时一定要空着手。这样,第一问的答案就为 ,第二问的答案就为长度>1的 极大递增连续段的数量。 反正贪心就可以,按队友思路写的代码: 1 // D-贪心 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<stack> 9 #include<map> 10 #include

BZOJ5287 HNOI2018毒瘤(虚树+树形dp)

女生的网名这么多〃 提交于 2021-01-21 03:55:06
  显然的做法是暴力枚举非树边所连接两点的选或不选,大力dp。考场上写的是最暴力的O(3 n-m n),成功比大众分少10分。容斥或者注意到某些枚举是不必要的就能让底数变成2。但暴力的极限也就到此为止。   每次重新dp做了大量重复的事,考虑从减少重复计算方面优化。 先跑一遍没有限制的树形dp。将非树边所连接的点拎出来建一棵虚树。注意到虚树中某点对其父亲的贡献系数(也即由该点到其父亲的链上点的dp值与其关系)是不变的,那么dp出系数,依旧暴力枚举非树边就可以了。一定程度上与noip2018d2t3有相似之处?   码起来非常长(虽然似乎并没有很难写),可能是我姿势不对。注意暴力枚举非树边时不应标记其是否强制被选,而是标记强制被选的次数,防止回溯时出问题。 #include<iostream> #include <cstdio> #include <cmath> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; #define ll long long #define N 100050 #define P 998244353 char getc(){ char c=getchar(); while ((c< ' A ' ||c> ' Z ' )&&(c< ' a ' ||c>

2013年蓝桥杯省赛C/C++A组真题解析

﹥>﹥吖頭↗ 提交于 2021-01-14 18:09:13
1、高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢? 高斯出生于:1777年4月30日。 在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。 高斯获得博士学位的那天日记上标着:8113 请你算出高斯获得博士学位的年月日。 提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21 此题的易错点在于是否要算上高斯出生的那天,以及输出格式。 C++解法: 1 // 从出生年开始算起,这种题一般都要掐头去尾,我直接把头加上了, 2 // 出生第一天也算是活了一天,所以加119就行, 3 4 #include<iostream> 5 using namespace std; 6 int month[ 13 ] = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 }; 7 int main() 8 { 9 int n; 10 while (cin >> n) 11 { 12 n += 119 ; 13 int year = 1777

Walking Between Houses(贪心+思维)

家住魔仙堡 提交于 2021-01-14 07:37:51
Walking Between Houses There are n n houses in a row. They are numbered from 1 1 to n n in order from left to right. Initially you are in the house 1 1. You have to perform k k moves to other house. In one move you go from your current house to some other house. You can't stay where you are (i.e., in each move the new house differs from the current house). If you go from the house x x to the house y y, the total distance you walked increases by | x − y | |x−y| units of distance, where | a | |a| is the absolute value of a a. It is possible to visit the same house multiple times (but you can't

NOI2016

一笑奈何 提交于 2021-01-14 05:50:31
luoguP1712 [NOI2016]区间 这是一道送分题. 对于我这种每天抄题解不动脑子思维僵化得厉害的智障选手就是送命题. 一直在想端点排序各种Treap搞... 正解: 已知一些区间,如何判断是否满足条件?满足条件是有一个点被覆盖的次数大于m,那么用线段树可以解决这个问题. 把区间按长度排序,从小往大考虑答案中选中最长区间的最大值. 加入一个新的区间,线段树上区间加,当最大值仍大于m时,按加入时间删去最早的区间即可. 1 // Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #include< set > 11 #include<map> 12 #define inf 0x7fffffff 13 #define For(i,a,b) for(int i=(a);i<=(b);i++) 14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--) 15 const int N= 1000007 ; 16 typedef long long LL; 17

codeforces 1151 D

落爺英雄遲暮 提交于 2021-01-14 05:41:29
SM的水题。 codeforces 1151D 当时写对了,因为第一题卡了,,然后这题就没细想,原来是没开longlong。 题意:n个位置每个位置有a和b,让sum=(每个点的左面的点的数量*a+右面点的数量*b)*n最小 理解:就是个小贪心,注意下开longlong就OK了 1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include < string > 6 #include <map> 7 #include <iomanip> 8 #include <algorithm> 9 #include <queue> 10 #include <stack> 11 #include < set > 12 #include <vector> 13 // const int maxn = 1e5+5; 14 #define ll long long 15 #define MAX INT_MAX 16 #define FOR(i,a,b) for( ll i = a;i <= b;++i) 17 // #define MOD 142857 18 using namespace std; 19 ll n,ans; 20 struct node 21 { 22 ll a,

【BZOJ】4318: OSU! 期望DP

北城余情 提交于 2021-01-13 07:37:47
【题意】有一个长度为n的01序列,每一段极大的连续1的价值是L^3(长度L)。现在给定n个实数表示该位为1的概率,求期望总价值。n<=10^5。 【算法】期望DP 【题解】后缀长度是一个很关键的量,设g[i]表示前i个的期望后缀长度。根据全期望公式,依赖于第i-1位为0或1:(以下所有公式最后省略+(1-ai)*0) $$g[i]=a_i*(g[i-1]+1)$$ 设f[i]表示前i个的期望长度,当第i-1位为1时,f[i]相对于f[i-1]的后缀多了[ (g[i-1]+1)^3 ] - [ g[i-1]^3 ]的代价,即: $$f[i]=f[i-1]+a_i*(3*g^2[i-1]+3*g[i-1]+1)$$ 等等,这没有结束,只有加法和乘法满足期望的线性, 不包括乘方 。通俗地说,期望的乘方不等于乘方的期望。 设g2[i]表示前i个的期望“后缀长度的平方”,同样的g2[i]相对于g2[i-1]多了[ (g[i-1]+1)^2 ] - [ g[i-1]^2 ],即: $$g_2[i]=a_i*(g_2[i-1]+2*g[i-1]+1)$$ 复杂度O(n)。 #include<cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn= 100010 ; double f

【BZOJ】4873: [Shoi2017]寿司餐厅

断了今生、忘了曾经 提交于 2021-01-13 02:54:21
【题目】 #2146. 「SHOI2017」寿司餐厅 【题意】给定n种寿司的代号,取区间[i,j]的寿司收益是d[i,j]和所有子区间的d,吃了c(c>0)种代号x的寿司的代价是mx^2+cx,给定n,m和矩阵d(有负数!),求最大收益。n<=100。 【算法】最大权闭合子图 【题解】开始考虑每个区间建一个收益点向区间内的寿司连边,然后对每个代号新建一个点权为-mx^2的点,每种寿司寿司连向代号点,这样就是求最大权闭合子图了。 但是这样边数是n^3,可能过不了。 考虑优化,区间$[i,j]$只需要连向$[i,j-1]$和$[i+1,j]$就可以了,所有区间$[i,i]$的点权为d[i,i]-a[i],这样边数只有n^2,复杂度O(n^4)。 #include<cstdio> #include <cstring> #include <algorithm> using namespace std; const int inf= 0x3f3f3f3f ; int n,m,S,T,a[ 110 ]; namespace nwf{ const int maxn= 20010 ,maxm= 40010 ; int tot= 1 ,first[maxn],d[maxn],q[maxn],cur[maxn]; struct edge{ int v,f, from ;}e[maxm* 2 ];

水题记录

ぃ、小莉子 提交于 2021-01-12 07:59:45
   从noip之后,自己的状态就非常不好。学文化课的时候心里总想着竞赛,真的停课了却又异常浮躁,简单题不想做,难题不会做,错了的题也不改,天天打游戏,静不下心。省选也是各种瞎打,day2T1竟然会因为没有memset掉了40分。虽说苟进了队,但毕竟进的不光彩,若是还以这样的状态下去,潦草离场,那当初选择这条路的意义又在哪里?   得开始好好学习了啊...... 4.16    正式停课的第一天~   昨天的HNOI考的巨炸,今天就先改改题   (老吴一大早分析了一波局势, dalao_cxy 被寄予厚望,Orz,要向他学习)   ~~~~~   只改了Day2两道题 http://www.cnblogs.com/XYZinc/p/8854765.html   还做了一道@cxy出的dp   今天效率好低啊 4.17    今天就主要打一些基础算法调整一下状态   ~~~~~ 贪心    「雅礼集训 2017 Day4」洗衣服    http://www.cnblogs.com/XYZinc/p/8862632.html    「雅礼国庆 2017 Day5」Repulsed   很容易想到贪心,对于所有未处理的点,在它的第k祖先处处理必然是最优的   f[i][j]表示节点i的子树中,距离为j且需要灭火器的点数   r[i][j]表示从节点i出发

线性筛素数、欧拉函数

社会主义新天地 提交于 2021-01-12 04:38:38
判断一个数n是否是素数,众所周知可以用O(sqrt(n))的方法。 但是如果要求很多个数,这个方法就不太好了。(比如所有小于n的数,复杂度就是O(n 1.5 )。) 埃拉托斯特尼筛法,大家都听说过。从2到n,去掉每个数的倍数,剩下来的就是质数。 不过这个方法会重复删除,比如6是2、3的倍数,会被删2次,因子越多,删的次数就越多。 改进之后的线性筛保证每个数只被最小的质因子删,所以是O(n)的。 #include<cstdio> #include <cstring> #define MAXN 100005 #define MAXL 1299710 int prime[MAXN]; int check[MAXL]; int tot = 0 ; memset(check, 0 , sizeof (check)); for ( int i = 2 ; i < MAXL; ++ i) { if (! check[i]) { prime[tot ++] = i; } for ( int j = 0 ; j < tot; ++ j) { if (i * prime[j] > MAXL) { break ; } check[i *prime[j]] = 1 ; if (i % prime[j] == 0 ) { break ; } } } View Code tot是计数用的,prime保存质数