
动归与递推
wanherun
今天会有好事发生吗
展开
-
bzoj5018 [Snoi2017]英雄联盟
题目嗯,其实吧,还是算比较显然的dp。 f[i][j]表示前i个英雄,用了j元钱的最多方案数,最后答案就是满足f[n][j]≥m最小的j了。f[i][j]表示前i个英雄,用了j元钱的最多方案数,最后答案就是满足f[n][j]\ge m最小的j了。 转移方法,首先,肯定要枚举i,然后枚举当前买几个皮肤j,再枚举l表示f[i][l]从什么转移过来。注意,每次l的上界是当前买所有皮肤的价格。转移方法,原创 2018-02-28 19:51:26 · 450 阅读 · 1 评论 -
bzoj1026 [SCOI2009]windy数
题目又是数位dp 只要套模板就好了。。。值得说明的是,这是第一道需要记录前缀0的数位dp233。#include<bits/stdc++.h>using namespace std;int dp[15][10][2];int digit[15];int m,n;int len;int DFS(int pos,int pre,int limit,int flag){ if(po原创 2017-09-08 22:29:35 · 198 阅读 · 0 评论 -
bzoj4300 绝世好题
题目绝世好题233。首先类似与最长不下降子序列的O(n^2)算法来写,很简单,对吧。 之后,如何优化。。 出现了位运算,显然要按照二进制位dp。。。 &不等于0,只要有一位都为1就好了,而且,这一位一直位1。dp转移就很好写了#include<bits/stdc++.h>using namespace std;int dp[35],tmp;int Ans;int n,A[100001]原创 2017-09-08 22:31:18 · 284 阅读 · 0 评论 -
bzoj1060 [ZJOI2007]时态同步
题目树上做递推 每个节点对答案的贡献为f[x]-f[to[i]]-val[i],val为边权,f[x]为节点到其叶子节点最长的路径长度。#include<bits/stdc++.h>#define N 500000using namespace std;int n,rt,x,y,z;int first[N+1],nex[2*N+1],to[2*N+1],val[2*N+1],siz;lo原创 2017-09-09 16:17:05 · 234 阅读 · 0 评论 -
bzoj2431 [HAOI2009]逆序对数列
题目这是一道dp题目。考虑转移f[i][j],此时,i是最大的,所以,无论插在哪里,都可以产生贡献。 for(int i=1;i<=n;i++) { f[i][0]=1; f[i][1]=i-1; for(int j=2;j<=k;j++) for(int k=1;k<=j+1&&k<=i;k++)原创 2017-09-09 16:18:36 · 216 阅读 · 0 评论 -
bzoj4521 [Cqoi2016]手机号码
题目一眼看出是数位dp,套模板就可以了。但可能我太菜了吧,只能算11位的,10位就完全错了,233。 导致强行特判233。求dalao们查错。#include<bits/stdc++.h>#define LL long longusing namespace std;LL dp[12][10][10][3][4];LL x,y;int digit[12],len;/* 0: 。原创 2017-09-09 16:19:52 · 282 阅读 · 0 评论 -
bzoj2111 [ZJOI2010]Perm 排列计数
题目转化一下题意,求有n个节点的小根堆一共有几种。那么,显然递推了。f[x]=C(x-1,left)*f[x-1-left]*f[left]left表示一个儿子的大小。 显然,记忆化好写很多。要用Lucas#include<bits/stdc++.h>#define LL long long#define MAXN 1000000using namespace std;LL fac[MAX原创 2017-09-10 19:32:46 · 222 阅读 · 0 评论 -
bzoj1911 [Apio2010]特别行动队
题目又是一道非常标准的斜率优化。一开始还以为需要讨论a来判断是维护上凸包还是下凸包,233。又看了眼数据范围,a一定小于0,嗯,这就轻松多了。 for(int i=1;i<=n;i++)A[i]=read(); for(int i=1;i<=n;i++)sum[i]=sum[i-1]+A[i]; for(int i=1;i<=n;i++) for(int j=0原创 2017-09-10 19:32:33 · 170 阅读 · 0 评论 -
bzoj1096 [ZJOI2007]仓库建设
题目看数据范围和直觉,可以知道,这应该是一道斜率优化的dp。n^2的转移方程很好想 for(int i=1;i<=n;i++)A[i]=A[i-1]+P[i]; for(int i=1;i<=n;i++)B[i]=B[i-1]+X[i]*P[i]; for(int i=1;i<=n;i++) { f[i]=C[i]+X[i]*A[i]-B[i];原创 2017-09-10 19:33:00 · 218 阅读 · 0 评论 -
bzoj1042 [HAOI2008]硬币购物
题目我们先考虑最最朴素的dp,像什么第几种硬币用了几枚的方法数,显然单次O(n^4)的吧,跑到宇宙毁灭的优秀算法233。如何优化呢?显然,如果硬币没有限制的话,就是一个十分简单的dp了f[0]=1;for(long long i=1;i<=4;i++) for(long long j=c[i];j<=N;j++) f[j]+=f[j-c[i]];之后加上了数量限制,怎么办呢原创 2017-09-11 21:48:22 · 224 阅读 · 0 评论 -
bzoj2748 [HAOI2012]音量调节
题目简简单单的dp。。。其实,也是可以滚动数组的,但是,我不想写233。。。#include<bits/stdc++.h>using namespace std;int n,maxlevel,x,beginlevel;bool f[51][1001];int main(){ scanf("%d%d%d",&n,&beginlevel,&maxlevel); memset(f原创 2017-09-07 14:22:43 · 246 阅读 · 0 评论 -
bzoj1833 [ZJOI2010]count 数字计数
题目数位dp裸题,再次套模板。注意如果是0的话,要注意前导0#include<bits/stdc++.h>using namespace std;int digit[15],len;long long dp[15][15][10][10];long long Ans[10][2],x,y;long long DFS(int pos,int limit,int pre,int id,long原创 2017-09-06 21:52:16 · 278 阅读 · 0 评论 -
bzoj1010 [HNOI2008]玩具装箱toy
题目又一道斜率dp裸题2333。朴素dp for(int i=1;i<=n;i++) read(C[i]); for(int i=1;i<=n;i++) sum[i]=sum[i-1]+C[i]; memset(f,63,sizeof(f)); f[1]=(sum[1]-L)*(sum[1]-L); for(int i=2;i<=原创 2017-09-06 21:51:21 · 236 阅读 · 0 评论 -
bzoj1597 [Usaco2008 Mar]土地购买
首先,这道题是bzoj120题,庆祝一下。题目其实,并不是第一次见这道题了,之前在某高中oj上见过,当时数据很小(n<=2000),单纯的写了一个n^2logn的做法,不过貌似出了点问题,只得了20分,不过之后就没管了。之后再见这道题,发现是一个比较简单的dp,O(n^2)的很好想,f[i]=min(f[j]+y[j+1]*x[i]), 但要注意的是,要先把没有用的土地除掉,不然会错误。不过这样还是原创 2017-08-28 20:11:01 · 273 阅读 · 0 评论 -
bzoj1260 [CQOI2007]涂色paint
题目一道区间dp。套路f[i][j],来表示,考虑转移。首先很好想到的是,如果不改变颜色,f[i][j]=min(f[i][k],f[k+1][j])毫无疑问。那么如果要换颜色呢。显然此时转移要s[i]与s[j]相等(不然没意义),f[i][j]=f[p][q]+1,s[p]==s[q],然后各路dalao说f[i][j]=Min(f[i+1][j],f[i][j-1],f[i+1][j-1]+1)原创 2017-08-28 21:17:09 · 362 阅读 · 0 评论 -
bzoj2326 [HNOI2011]数学作业
某次noip模拟赛遇见了,打完后发现它,二话不说就A了。题目其实就是简单的矩阵快速幂,构造矩阵 {10^a,0,0} {1, 1,0} {0, 1,1} 在乘一乘,处理细节,就好了。#include<cmath>#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#inclu原创 2017-08-28 21:22:07 · 354 阅读 · 0 评论 -
bzoj1237 [SCOI2008]配对
题目dp题目,首先看数据范围,可得应该是接近O(n)的算法,我们先处理一下,把两个数组从小到大排序,再找找规律,发现转移只在三个数之间进行,我们画个图理解一下。如果超过4个肯定没有这样优秀。代码比较简单。#include<bits/stdc++.h>#define N 100000#define Min(x,y,z) min(x,min(y,z))using namespace std;co原创 2017-08-30 07:40:09 · 268 阅读 · 0 评论 -
bzoj4562 [Haoi2016]食物链
题目输入符合生物学特点233,所以这就应该是一个有向无环图,我们尝试在上面做dp。显然,f[i]=sigma(f[u]),u连向x,按照拓扑序来。 注意统计答案时,只记录出度为0的点。 当然,一个点不能算食物“链”233#include<bits/stdc++.h>#define N 100000using namespace std;int n,m,x,y,ans;int f[N+1]原创 2017-08-30 07:42:46 · 631 阅读 · 1 评论 -
bzoj4993 [Usaco2017 Feb]Why Did the Cow Cross the Road II
题目一道dp水题,思想和最长公共子序列差不多,练习一下233。没有代码。原创 2017-08-30 07:43:21 · 437 阅读 · 1 评论 -
bzoj3156 防御准备
题目又是一道斜率dp题 而且还是套路题。一般转移 for(LL i=1;i<=n;i++)A[i]=read(); for(LL i=1;i<=n;i++)sum[i]=(LL)sum[i-1]+i; f[1]=A[1]; for(LL i=2;i<=n;i++) { f[i]=~0u>>1; for(LL j=1;j<i;j+原创 2017-08-31 07:41:02 · 222 阅读 · 0 评论 -
bzoj3437 小P的牧场
题目斜率优化第一题。。。其实熟悉之后,发现其实并没有什么难度,就是数学推公式就好了朴素dp for(register LL i=1;i<=n;i++)scanf("%lld",&a[i]); for(register LL i=1;i<=n;i++)scanf("%lld",&b[i]); for(register LL i=1;i<=n;i++)A[i]=A[i-1]+b[i原创 2017-08-31 07:41:52 · 199 阅读 · 0 评论 -
bzoj1003 [ZJOI2006]物流运输
题目预处理cost[i,j]表示第i天到第j天都跑这条路的最短路。也就是说保证路径上的所有点在i到j天都可以跑的前提下的最短路。 然后dp。f[i]表示前i天的最小费用,那么f[i]=min{f[j]+cost[j+1,i+k]} ,初始值f[i]=cost[1,i]。 先用spfa预处理。然后转移的时候O(1)就好了。#include<bits/stdc++.h>#define LL原创 2017-09-02 20:50:49 · 514 阅读 · 0 评论 -
bzoj1089 [SCOI2003]严格n元树
题目递推公式:f[i]=f[i-1]^n+1当然,这样看的话显然long long是存不下的233。要用高精度对吧,但是,我很懒呀。so,粘个模板吧。//#include<bits/stdc++.h>//using namespace std;//long long f[17];//int n,d;//long long ksm(long long A,long long B)//{//原创 2017-09-11 21:48:38 · 211 阅读 · 0 评论 -
bzoj4720 [Noip2016]换教室
题目震惊,noip竟然考期望dp233。 期望是可以递推的。。。。 f[i][j][0..1]表示第i节课,已经换了j节,第i节换不换教室的期望。这样,就有四种转移,也比较好写,太长了,就不打出来了,看代码吧。#include<bits/stdc++.h>#define MIN(x,y,z) min(min(x,y),z)using namespace std;int n,m,v,e;i原创 2017-09-11 21:52:32 · 205 阅读 · 0 评论 -
[noip2016]愤怒的小鸟 题解
n好小啊,当时十分年轻地写了搜索,自己的数据跑得贼快,但是最终测评只有60+呀,不过,这数据范围,不应该一眼看出状压dp吗,而且还十分简单233。考虑每一条抛物线,最多只能有n^2级的数量,还是很小的,可以承受,然后就是状态转移了,每条抛物线都可以转移一次。大概的复杂度是O(n^2*2^n),还是轴对称的233。 #include<bits/stdc++.h>using namespace std原创 2017-10-20 23:06:55 · 1024 阅读 · 0 评论 -
[noip2015]子串 题解
可以说是出得十分好的一道dp题目了,要用到滚动数组,前缀和优化。首先,我们考虑状态,f[k][i][j]表示第一个串到i位,第二个串到j位,分了k段的方案数。 首先,如果s1[i]==s2[j]的话,f[k][i][j]=sigema(f[k-1][l][j-1])(0<=l#include<bits/stdc++.h>#define mod 1000000007using namespace原创 2017-10-22 17:44:36 · 538 阅读 · 1 评论 -
[noip2014]飞扬的小鸟 题解
其实,这道题本质实在不难,一眼可以看出dp相关,不过细节比较多。 f[i][j]表示,在i,j的最少点击数。首先,考虑上升的情况,每次可以升随意次,那么f[i][j]=min(f[i][j-k*X[i]]+K)了,但是我们显然要去掉k,就可以采用完全背包的思路。 f[i][j]=min(f[i-1][j-X[i]],f[i][j-X[i]])+1,就好了。下降没什么好说的,就一个0/1背包,注意原创 2017-10-24 23:05:43 · 554 阅读 · 0 评论 -
bzoj3450 Tyvj1952 Easy
题目比较简单的一个期望递推,设当前连续o的期望为tmp,则如果当前为x,tmp=0,对答案没有贡献。 如果当前为o,tmp++,对答案有tmp^2-(tmp-1)^2的贡献 如果当前为?,先对答案有((tmp+1)^2-tmp^2)的贡献,tmp=(tmp+1)/2。按照这个规则,O(n)扫一遍就可以了。#include<bits/stdc++.h>using namespace std;i原创 2017-11-09 14:14:36 · 187 阅读 · 0 评论 -
bzoj1669 [Usaco2006 Oct]Hungry Cows饥饿的奶牛
题目最,最,最长上升子序列。可以说是很简单了。唯一需要注意的是要把f数组一开始赋值为1.#include<bits/stdc++.h>#define N 5000using namespace std;int f[N+5],A[N+5],n,mx;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; retur原创 2017-11-09 14:39:54 · 433 阅读 · 0 评论 -
bzoj3997 [TJOI2015]组合数学
题目emm,首先,记住一个定理一样的东西:最长反链=DAG最小路径覆盖然后,就是比较简单的一个dp问题了。#include<bits/stdc++.h>#define Max(a,b,c) max(a,max(b,c))using namespace std;int n,m,T;int A[1005][1005],f[1005][1005];inline char nc(){原创 2017-11-09 14:46:24 · 300 阅读 · 0 评论 -
bzoj1925 [Sdoi2010]地精部落
题目很熟悉的一道题目,很久以前记过一个结论。说到底就是波动数列计数。 运用递推思想。f[i][j]=f[i][j-1]+f[i-1][j-i]但是这道题要卡空间,要开一个滚动数列就好了。#include<bits/stdc++.h>using namespace std;long long n,p,now;long long f[2][4205];int main(){ //f原创 2017-11-09 14:55:41 · 262 阅读 · 0 评论 -
bzoj2134 单选错位
题目博客要开始更新了。毕竟noip也算过去了。这差不多又是一道数学题,我们这样考虑:对于一道答案有a种情况,会选b种可能的题,两两排一下,一共有ab种情况,而符合条件的只有min(a,b)种,那么,期望为(1/ab)*min(a,b),也就是1/max(a,b)。之后就是O(n)累加就好了。#include<bits/stdc++.h>#define N 10000000using namesp原创 2017-12-03 18:43:07 · 292 阅读 · 0 评论 -
bzoj4742 [Usaco2016 Dec]Team Building
题目一眼dp题,对吧,然后就是考虑状态的表示与转移了。有两个数组,f[i][j]是肯定要有的,然后选k个,最终状态就为f[i][j][k]就好了。表示a中前i个与b中前j个,选出了k个的方案数。(当然顺序对于这道题没有影响,但是要先排一个序。)转移:f[i][j][k]=f[i−1][j][k]+f[i][j−1][k]−f[i−1][j−1][k]f[i][j][k]=f[i-1][j][k]+f原创 2017-12-10 09:08:30 · 349 阅读 · 0 评论 -
[noip2016]换教室 题解
其实noip考期望就很是可以了,不过,只要大概知道一点期望的知识就可以做出来了。考虑dp。 每两个教室之间的最短路可以用Floyd预处理,以后O(1)用就好了。 状态f[i][j][0…1]表示前i间教室,换了j间,第i间换不换的期望。每个状态可以这样更新而来: dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][0]+(double)dis[c[i]][c[原创 2017-10-20 00:05:57 · 416 阅读 · 0 评论 -
bzoj1755 [Usaco2005 qua]Bank Interest
题目深夜水题,利滚利,问最终得到的钱的整数部分。#include<bits/stdc++.h>using namespace std;int n,A[100005];inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,原创 2017-10-17 23:35:40 · 206 阅读 · 0 评论 -
bzoj3407 [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题
题目转化了一下的0/1背包问题,相当于体积和价值都是A[i],跑一遍就好了。#include<bits/stdc++.h>#define N 500using namespace std;int H,n;int A[N+5];int f[45005];inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; r原创 2017-10-12 22:45:19 · 457 阅读 · 0 评论 -
bzoj1072 [SCOI2007]排列perm
题目令人窒息的一道(shui)题。 纯暴力地考虑。 用next_permutation求下一个排列,set去重。这样可是能过的呀。 scanf("%d\n",&T); while(T--) { scanf("%s",s);scanf("%d\n",&p); len=strlen(s); for(int i=1;i<=len;i原创 2017-09-17 11:28:58 · 212 阅读 · 0 评论 -
bzoj1342 [Baltic2007]Sound静音问题
题目显然是单调栈的裸题呀,就滑动窗口来更新,最大最小值,最后判断一下就好了。#include<bits/stdc++.h>#define N 1000000using namespace std;int n,A[N+1],m;int l,r,q[N+1],c;int mx[N+1],mn[N+1]; bool flag;inline char nc(){ static cha原创 2017-09-23 23:51:01 · 356 阅读 · 0 评论 -
bzoj1600 [Usaco2008 Oct]建造栅栏
题目首先我们需要知道,四条边要构成四边形,必须每条边都小于周长的一半。之后就十分简单了。dp呀什么的都可以做了。记住结论。#include<bits/stdc++.h>using namespace std;int n,lim;int f[3000];int ans;int main(){// freopen("in.txt","r",stdin); cin>>n;原创 2017-09-23 23:57:43 · 240 阅读 · 0 评论 -
bzoj3687 简单题
题目根据异或的性质可知,偶数个相同的数是没有影响的。之后就是简单dp了,但是,这道题可以用bitset这一神奇东西,当然得学习一下了。#include<bits/stdc++.h>#define N 2000010using namespace std;int n,x;long long ans;bitset <N> f;int main(){ freopen("in.txt"原创 2017-09-26 10:52:11 · 313 阅读 · 0 评论