动态规划专题

其实已经做了不少题了,开个坑记一下在之前培训中遗留下来的题

CF327E 状压dp水题。一个小trick,如何比线性快的获取S的每位二进制?
for(int i = S;i;i -= lowbit(i))dp[S] += dp[S & ~lowbit(i)]要比每位分别判断要快

BZOJ4057 对于S中每位1,可以先预处理一下再枚举(注意这种情况是要在复杂度大于线性的时候用,否则就失去意义了,预处理跑的比算法还慢)

CF1101D 遇见gcd/lcm 考虑质因数

CF1039D 根号分治,显然当kn的时候答案最大是n,因此不同的答案数是O(n)级别的。对k较大的部分使用二分。考虑对于某个给定的k如何计算。设dp[i]表示以 i 为根节点的子树的答案,转移贪心即可。时限 7s 依旧是个卡常的辣鸡题。树形dp时可以用逆dfs序模拟递归过程,记录一下父亲并转移即可。时间复杂度O(nlognn)最大点只需要跑1.2s

Luogu4161 / 6280 见题解

Luogu1365 设dp[i]表示考虑到位置 i 的期望。考虑combo,如果是 o 则combo+1,x则combo=0,? combo有一般概率 +1 一半概率 = 0,因此= (.+1)/2

Luogu1006 dp[i][j][k][l]表示传到(i,j),(k,l)的最大值,转移显然

Luogu1850 dp[i][j][0/1]表示当前在第 i 时间段,加上本次一共用了 j 次机会,当前申请 / 没有申请的最小期望路程。转移分情况讨论,例如:dp[i][j][1]=dp[i1][j1][1]+(k[i1])(k[i])dis[d[i1]][d[i]]+(k[i1])(1k[i])dis[d[i1]][c[i]]+(1k[i1])k[i]dis[c[i1]][d[i]]+(1k[i1])(1k[i])dis[c[i1]][c[i]],其余转移同理

Luogu4322 浮点二分答案之后转化为经典的(有总元素个数限制的)树形背包,直接写复杂度是O(nK2)的,但是如果我们将K和size取个min,就可以做到O(nk),直接dfs会被卡常

CF1097G 利用斯特林数降幂之后变成一个C(f(X),i)对X求和的形式,考虑其组合意义,类似于一个树形背包。细节略多,感觉没有完全理解

CF1061C dp[i][j]表示原数列到位置 i,子序列到 j的方案数,转移对a[i]的因子枚举即可。注意需要滚动数组,而常规写法dp[i&1][j]会超时,只能改成dp[j]一类的,注意转移顺序!

CF886E 设f[i]表示考虑1~i的排列,其中能使程序运行到结尾的方案数。显然运行到结尾的一个必要条件就是i位于[ik+1,i],考虑枚举i的位置转移。f[i]=j=ik+1if[j1]Ci1ij(ij)!,化简可得f[i]=(i1)!j=ik+1if[j1](j1)!,后面的和式显然可以用前缀和维护。考虑统计答案,先考虑结果正确的方案数,即枚举n的位置,是i=1nf[i1]Cn1ni(ni)!,用n!减去即可。
注意这种只关注相对大小的题,可以考虑用一个相对大小相同的排列代替,然后乘以一个组合数即可

CF1096D 设dp[i][0/1/2/3]表示考虑到第i个位置,"hard"没有出现/出现了h/ha/har的最小代价

CF1043F 观察到一个关键性质:如果有解,答案一定不会超过7(每次有一个新元素加进来之后gcd一定会除以一个质因子,否则gcd不变,这个数删去答案更优,这里不考虑gcd=2^2, 2^3.. 的情况是因为取一个质因数次数更小的数,答案一定不会变差,而2*3*5*7*11*13*17>3e5),枚举答案长度len,设dp[i]表示当前len,集合gcd为i的方案数。设cnt[i]表示a中有多少数能被i整除,显然可以预处理得到。那么转移就是dp[i]=C(cnt[i],len)dp[j],i|jj>i,最后判断一下dp[1]是否不为0即可。注意这个题不是对答案进行dp,而是用dp判断类似可能性一类的问题

Luogu1450 如果没有限制,就是一个完全背包了;如果有一个钱的限制,答案就是dp[S]dp[SC[i](D[i]+1)],原因是考虑钦定拿出D[i]+1个C[i],然后剩下的随便选。如果有2,3,4个也一样,容斥一下即可

Luogu2627 单调队列优化dp。设dp[i]表示考虑到第 i 个且钦定 i 不选的答案,式子写出来之后单调队列维护dp[j]sum[j]即可。注意2个细节:ik+1的时候需要额外初始化;以及最后需要额外计算n也选了的情况

51nod1636 / CF119C
首先按照难度排序,注意到 biai 很小,以此设计状态:设 dp[i][lst][delta] 表示当前第 i 天,上一天选了第 lst 们课,delta就是 lst.a + delta 表示今天的作业量,转移枚举一下下一天上哪个课,注意判断一下状态是否合法!!

CF533B
dp[x][0/1] 表示 xx 的子树中有 偶数/奇数 个在集合中的最大权值
然后考虑转移:dp[x][0]=max(dp[x][0]+dp[u][0],dp[x][1]+dp[u][1])dp[x][1]=max(dp[x][1]+dp[u][0],dp[x][0]+dp[u][1]),(为什么要记录奇数的情况?有可能是多个奇数组合形成的下属个数为偶数),然后统计完子树答案之后考虑 x 这个点。前面 dp 值是没考虑 x 的结果,显然如果 dp[x][0] 的情况下,x 就可以选,也就是 dp[x][1]=max(dp[x][1],dp[x][0]+a[x]) ,这样也保证了 x 的状态是合法的(如果x的子树选了奇数个,那么x一定不选,否则x可能选),数学归纳法得到所有的dp值都是合法的。最后答案就是 max(dp[1][1],dp[1][0]),注意 dp[x][1]=inf 初始化,因为转移的时候认为 dp[x][0/1] 表示的是不含 x 的子树的情况,而开始时相当于空树,含奇数的情况不存在

posted @   SkyRainWind  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示