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

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

[TC13761]Mutalisk

题目大意:

\(n(n\le20)\)个坏人,第\(i\)个坏人的血量为\(A_i(A_i\le60)\)。你可以每次攻击\(3\)个坏人,并分别造成\(9\)点、\(3\)点、\(1\)点伤害。问最少需要多少次攻击使得所有坏人血量都\(\le0\)

思路:

二分+DP。

\(f_{i,j,k}\)表示前\(i\)个坏人,还有\(j\)次扣\(9\)点血的机会、\(k\)次扣\(3\)点血的机会,最多还能有几次扣\(1\)点血的机会。

源代码:

#include
#include
class Mutalisk { private: static constexpr int N=21,M=101; int n,a[N],f[N][M][M]; void upd(int &a,const int &b) { a=std::max(a,b); } bool check(const int &m) { memset(f,-1,sizeof f); f[0][m][m]=m; for(register int i=1;i<=n;i++) { for(register int j=0;(j-1)*9<=a[i]&&j<=m;j++) { for(register int k=0;(j-1)*9+(k-1)*3<=a[i]&&j+k<=m;k++) { const int l=std::max(a[i]-j*9-k*3,0); if(j+k+l>m) continue; for(register int a=j;a<=m;a++) { for(register int b=k;b<=m;b++) { upd(f[i][a-j][b-k],f[i-1][a][b]-l); } } } } } for(register int i=0;i<=m;i++) { for(register int j=0;j<=m;j++) { if(f[n][i][j]!=-1) return true; } } return false; } public: int minimalAttacks(std::vector
x) { n=x.size(); for(register int i=1;i<=n;i++) { a[i]=x[i-1]; } int l=1,r=100; while(l<=r) { const int mid=(l+r)>>1; if(check(mid)) { r=mid-1; } else { l=mid+1; } } return r+1; }};

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

你可能感兴趣的文章
linux常用命令(用户篇)
查看>>
获取组件的方式(方法)
查看>>
win2008 server_R2 自动关机 解决
查看>>
我的友情链接
查看>>
在C#调用C++的DLL简析(二)—— 生成托管dll
查看>>
Linux macos 常用终端操作
查看>>
企业网络的管理思路
查看>>
Linux磁盘分区与挂载
查看>>
J2se学习笔记一
查看>>
DNS视图及日志系统
查看>>
老李分享:Android性能优化之内存泄漏 3
查看>>
mysql命令
查看>>
来自极客标签10款最新设计素材-系列七
查看>>
极客技术专题【009期】:web技术开发小技巧
查看>>
PHP 简单计算器代码实现
查看>>
正则表达式的知识普及
查看>>
docker使用笔记
查看>>
华为eNSP模拟器上实现FTP服务
查看>>
【全球AI人才排行榜】美国第一,中国仅排名第7
查看>>
微信小程序输入框input
查看>>