博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[CF413D]2048
阅读量:6069 次
发布时间:2019-06-20

本文共 921 字,大约阅读时间需要 3 分钟。

题目大意:

  在一个长度为$n(n\le2000)$的数组中填数$2$或$4$,待所有数字全部填好后,按照类似于2048的规则向左合并。给定某些格子上的数,问在当前情况下要使得合并后的最大数超过$2^k$有几种填法。

思路:

  动态规划。
  定义一个状态为最长不上升后缀的数字和,如$(16,4,8,4,4,2)$对应的状态为$18$,因为后面这些还是有机会合并的,且合并的过程可以直接用加法代替,如$(16,4,8,4,4,2)$后面再加上一个$2$,对应的状态变为$18+2=20$。定义目标状态为$2^k$,超过这个的状态对其取$\min$。用$f[i][j]$表示前$i$个格子状态为$j$的方案数,则不难得到如下转移:
  当$x=2$时,$f[i][\min(j+2,2^k)]+=f[i-1][j]$;
  当$x=4$且当前最后有多余$2$时,新加进来的数不可能再和前面的合并了,故不将前面的计入状态,$f[i][4]+=f[i-1][j]$;
  当$x=4$且当前最后无多余$2$时,$f[i][\min(j+4,2^k)]+=f[i-1][j]$。
  当$x$不确定时,同时进行上述两种转移即可。
  时间复杂度$O(n\cdot2^k)$。

1 #include
2 #include
3 #include
4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x;10 }11 const int K=10,mod=1e9+7;12 int f[2][(1<

 

转载于:https://www.cnblogs.com/skylee03/p/8987373.html

你可能感兴趣的文章
《Advanced Linux Programming》读书笔记(1)
查看>>
zabbix agent item
查看>>
一步一步学习SignalR进行实时通信_7_非代理
查看>>
AOL重组为两大业务部门 全球裁员500人
查看>>
字符设备与块设备的区别
查看>>
为什么我弃用GNOME转向KDE(2)
查看>>
Redis学习记录初篇
查看>>
爬虫案例若干-爬取CSDN博文,糗事百科段子以及淘宝的图片
查看>>
Web实时通信技术
查看>>
第三章 计算机及服务器硬件组成结合企业运维场景 总结
查看>>
IntelliJ IDEA解决Tomcal启动报错
查看>>
默认虚拟主机设置
查看>>
七周五次课(1月26日)
查看>>
Linux系统一些系统查看指令
查看>>
php中的短标签 太坑人了
查看>>
[译] 可维护的 ETL:使管道更容易支持和扩展的技巧
查看>>
### 继承 ###
查看>>
数组扩展方法之求和
查看>>
astah-professional-7_2_0安装
查看>>
函数是对象-有属性有方法
查看>>