zoukankan      html  css  js  c++  java
  • DP刷题记录

    (DP)太菜了,开个随笔稍微记录一下

    关路灯

    挺经典一题

    (f[l][r][0/1])表示关掉([l,r])内的路灯后在左侧还是右侧

    然后转移方程

    (f[l][r][0]=min(f[l+1][r][0]+d[l][l+1]*(s[n]-s[r]+s[l]),f[l+1][r][1]+d[l][r]*(s[n]-s[r]+s[l])))

    (f[l][r][1]=min(f[l][r-1][0]+d[l][r]*(s[n]-s[r-1]+s[l-1]),f[l][r-1][1]+d[r-1][r]*(s[n]-s[r-1]+s[l-1])))

    打砖块

    不能直接背包,因为不知道最后一个(Y)到底有没有子弹

    预处理(v[i][j][0/1])表示第(i)列用(j)发子弹,最后一发打在(N/Y)

    也就是说遇到一个(N)上面是(Y)的情况,可以把上面的(Y)压缩到下面的(N)上,用(1)来表示

    如果不是这种情况就把(v[i][j][0])(v[i][j][1])一起用(v[i][j-1][1])更新

    设计(f[i][j][0/1])表示前(i)列用(j)发,最后一发是(N/Y)的最大值

    然后就可以了,如果枚举哪一列,一共用了几发,这一列用几发

    转移要注意的有点多:

    (1.f[i][j][1]=max(f[i-1][j-k][1]+v[i][k][1]))

    表示如果一直有子弹可以借从别的地方借一个打掉最上面的(Y)再还回去的最大值

    (2.if(k) f[i][j][0]=max(f[i-1][j-k][1]+v[i][k][0]))

    这个表示从当前列借一发子弹给前面的列,得到的最大结果

    (3.if(j>k) f[i][j][0]=max(f[i-1][j-k][0]+v[i][k][1]))

    这个表示从前面的某一列借一发给当前列,得到的最大结果

    答案是(max(f[m][j][0]))

    迎接仪式

    (f[i][j][k][0/1])表示到(i)位置,有(j)(0)变成(1),有(k)(1)变成(0),结尾是(0/1)

    然后就……(ning)转移,最后取(max{f[n][i][i][0/1]})

    时态同步

    就……求出最长的,然后树上模拟??

    然后……数组忘了调大+(sb)错误(WA)了两发

    低价购买

    这都能蓝?黄的差不多

    问最长严格下降子序列长度,和数值不同的最长严格下降子序列个数

    第一问(O(n^2)dp),第二问我们发现,只要边(dp)边记录次数,然后往前更新答案的时候遇到同样的数字就(break)就行了

    道路游戏

    (s[i][k])表示在(i)时刻(k)这个位置的前缀和,注意每个时刻机器人位置都变化所以这个前缀和是错位的……

    然后就可以得到(O(n^3))(dp)方程:(f[i]=max{f[i-k]+s[i][j]-s[i-k][(j-k+p*n)\%n]-w[(j-k+p*n)\%n]})

    其中(i)是时间,(j)是当前位置,(k)是设定的移动距离

    然后卡过了

    为了有脸还是优化一下

    然后我们变形一下方程得到 (f[i]=max{f[i-k]-s[i-k][(j-k+p*n)\%n]-w[(j-k+p*n)\%n]}+s[i][j])

    那单调队列维护一下前面这个(max)里的东西就好了

    写起来稍微有点麻烦

    统计单词个数

    先求出(f[l][r])表示([l,r])内能分出多少个单词,只要枚举(r)然后倒推(l)就可以(O(n^2))实现

    然后(dp[i][k])表示到(i)分了(k)段的最大答案,注意(k<=i)

  • 相关阅读:
    PHP实现发送模板消息(微信公众号版)
    laravel 跨域问题
    微信授权登录
    支付demo2
    支付demo1
    微信支付注意点
    微信支付方式区分
    debian,dietpi,linux中文乱码解决方法
    嵌入式应该深入专研STM32还是继续学习linux内核驱动呢?
    arduino下载ESP8266开发板的方法
  • 原文地址:https://www.cnblogs.com/knife-rose/p/12207415.html
Copyright © 2011-2022 走看看