题目描述

经过小FF的研究,他发现蚂蚁们每次都走同一条长度为n个单位的路线进攻, 且蚂蚁们的经过一个单位长度所需的时间为T秒。也就是说,只要小FF在条路线上布防且给蚂蚁造成沉痛伤害就能阻止蚂蚁的进军。

SCV擅长制造的防御塔有三种,分别是激光塔,放射塔和干扰塔, 他们可以在一个单位长度内修建一座防御塔。三种防御塔的作用如下:

激光塔: 使用高能激光,当蚂蚁从塔前经过时每秒对蚂蚁造成r点伤害。

放射塔: 释放放射性元素, 当蚂蚁经过这座塔后,每一秒受到g点伤害。

干扰塔: 干扰塔负责干扰蚂蚁们的信息素,使得蚂蚁在经过这座塔后,经过之后每一个单位长度的时间变成T+b。

当然, 放射塔和干扰塔的效果是可以叠加的, 也就是说如果敌人经过x座放射塔,那么敌人每秒钟会受到x * g点伤害; 同理,如果敌人经过y座干扰塔, 那么敌人经过一个单位长度的时间将变为T+y * b。

现在距离蚂蚁的下一轮进攻还有足够长的时间,你这个“NewBe_One”计划的首席工程师现在被任命为战略总参谋长, 因此你必须设计一个给蚂蚁们造成最大伤害的布塔方案。

输入格式

输入数据仅一行, 5个整数 n, r, g, b, T中间用一个空格隔开。 它们分别表示你可以布防的总长度, 激光塔的效果、 放射塔的效果和干扰塔的效果。

对于30%的数据: 1<=n<=20;

对于60%的数据: 1<=n<=1024;0<=r, g, b<=65536;0<=T<=3;

对于另外40%的数据:1<=n<=400;0<=r, g, b<=2^31-1;0<=t<=1000.

输出格式

输出仅一个整数, 代表你的方案给敌人带来的最大伤害值。


我们先逮着400的数据下手:

这道题最好想的就是动态规划了,几个状态一开出来直接转移即可。首先设dp(i,j,k,l,0/1/2),其中i表示当前在第i个位置,已经放置了j个放射塔,并且放了k个干扰塔和l个激光塔,0表示i这个位置放放射塔,1表示干扰塔,2表示激光塔。先不管爆内存的事,列出状态转移方程:

\[ dp[i][j][k][l][0]=Max_{0≤x≤2}{\{}dp[i-1][j-1][k][l][x]{\}}+g*(j-1)*(t+k*b)\\ dp[i][j][k][l][1]=Max_{0≤x≤2}{\{}dp[i-1][j][k-1][l][x]{\}}+g*j*(t+(k-1)*b)\\ dp[i][j][k][l][2]=Max_{0≤x≤2}{\{}dp[i-1][j][k][l-1][x]{\}}+(g*j+r)*(t+k*b) \]

可以发现每个状态都由上一个状态的最大值更新而来,所以我们可以省掉最后一维,让dp数组自带Max:

\[ ans0=dp[i-1][j-1][k][l]+g*(j-1)*(t+k*b)\\ ans1=dp[i-1][j][k-1][l]+g*j*(t+(k-1)*b)\\ ans2=dp[i-1][j][k][l-1]+(g*j+r)*(t+k*b)\\ dp[i][j][k][l]=Max{\{}ans0,ans1,ans2{\}} \]

然后我们发现,更新dp数组时我们只需要用到第i-1和第i位的信息,i-2及之前的地方都浪费了,所以我们可以把它滚掉:

\[ ans0=dp[!d][j-1][k][l]+g*(j-1)*(t+k*b)\\ ans1=dp[!d][j][k-1][l]+g*j*(t+(k-1)*b)\\ ans2=dp[!d][j][k][l-1]+(g*j+r)*(t+k*b)\\ dp[d][j][k][l]=Max{\{}ans0,ans1,ans2{\}},d{\in}[0,1] \]

然后我们又发现,每个位置必须放一个塔,不然显然没有防塔的优。那么当我们枚举到i这个位置时,我们可以由i-j-k推出l的值。所以我们只需要三层循环就够了。并且由于j,k确定之后,l也是确定的,那么我们可以干脆掐掉l这一维:

\[ ans0=dp[!d][j-1][k]+g*(j-1)*(t+k*b)\\ ans1=dp[!d][j][k-1]+g*j*(t+(k-1)*b)\\ ans2=dp[!d][j][k]+(g*j+r)*(t+k*b)\\ dp[d][j][k]=Max{\{}ans0,ans1,ans2{\}},d{\in}[0,1] \]

然后经过提交发现,d这一维要不要都无所谓。其实感性地证明一下也是可以得出这个结论的。那么:

\[ ans0=dp[j-1][k]+g*(j-1)*(t+k*b)\\ ans1=dp[j][k-1]+g*j*(t+(k-1)*b)\\ ans2=dp[j][k]+(g*j+r)*(t+k*b)\\ dp[j][k]=Max{\{}ans0,ans1,ans2{\}} \]

那么最初级的算法就设计出来了,时间复杂度为O(N^3)。然后发现开O2可以过?


N^3显然不是正解。

我们看到上面暴力的最终转移方程,可以发现我们的dp数组只与放置的塔的个数有关,与当前在哪个位置无关,那么可以这么认为:上面的暴力算法中枚举位置时其实是在确定激光塔的数量。所以说我们只需要枚举j和k,而l可以直接n-j-k得出,所以我们只需要两层循环。不过伤害值怎么算?

我们分析一下题目:

如果我们在中间放下激光塔,即它的后面还有放射塔和干扰塔,那么可以发现我们把随便一个后面的放射塔和干扰塔拿来给激光塔换一下都会更优。进一步我们得出一个结论:激光塔必定放在末尾的位置,并且是连续的一串激光塔。

所以我们可以枚举了j和k之后直接根据j和k算出激光塔的伤害了。具体看代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1025
using namespace std;__int128 dp[maxn][maxn];
__int128 n,r,g,b,t;
__int128 ans;inline __int128 read(){register __int128 x(0),f(1); register char c(getchar());while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}void print(__int128 x){if(!x) return;print(x/10);putchar(x%10+'0');
}int main(){n=read(),r=read(),g=read(),b=read(),t=read();//先计算放射塔和干扰塔的伤害,激光塔最后算for(register int i=1;i<=n;i++){for(register int j=0;i+j<=n;j++){if(!j) dp[i][j]=dp[i-1][j]+g*(i-1)*(t+j*b);else dp[i][j]=max(dp[i-1][j]+g*(i-1)*(t+j*b),dp[i][j-1]+g*i*(t+(j-1)*b));}}//找最大值作为答案,并且加上激光塔的伤害for(register int i=0;i<=n;i++){for(register int j=0;i+j<=n;j++){register int k=n-i-j;if(k) ans=max(ans,dp[i][j]+(g*i+r)*k*(t+j*b));}}print(ans);return 0;
}

* 数据需要开高精,为了可读性(和懒)代码用了__int128。

转载于:https://www.cnblogs.com/akura/p/11000224.html

luogu P2198 杀蚂蚁相关推荐

  1. 洛谷-P2198 杀蚂蚁

    Solution 大致感受一下,我们就可以发现似乎激光塔一定要放在最末尾才能最大化一个激光塔给蚂蚁的伤害,所以所有的激光塔我们强制全部放在最末尾.然后呢,我们需要把前面的多余空位合理安排给放射塔和激光 ...

  2. zjoi 2008 杀蚂蚁

    题目描述 最近,佳佳迷上了一款好玩的小游戏:antbuster. 游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的任务,就是用原 ...

  3. [BZOJ1033][ZJOI2008]杀蚂蚁antbuster(大模拟)

    题目描述 传送门 题解 bz的题面真心不爽,建议去codevs 比较良心的一道大模拟,题面写的比较清楚,也没有什么坑 几个需要注意的地方 1.对于每一只蚂蚁来说,年龄=秒数-1 2.选择方向的过程是: ...

  4. 【BZOJ1033】[ZJOI2008]杀蚂蚁antbuster【模拟】

    (´:ω:`) 有以下几点要注意: 1,蚂蚁不是质点. 2,蚂蚁的直径是1,不是半径是1. 3,给蚂蚁按age排序的时候,不要忘了target也得跟着变. 4,过早优化就是死,直接维护信息素的值就好了 ...

  5. BZOJ1972:[SDOI2010]猪国杀

    我对模拟的理解:https://www.cnblogs.com/AKMer/p/9064018.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem ...

  6. [SDOI2010] 猪国杀

    NOIp前最后皮一下,祝自己RP++. 从昨天晚上开始写,一直写到现在才A...... 在LXD大佬的帮助下,终于A掉了...... 还发现有两道大模拟,一个是琪露诺的冰雪小屋,一个是杀蚂蚁,有兴趣的 ...

  7. [日常] NOIP前集训日记

    写点流水账放松身心... 10.8 前一天考完NHEEE的一调考试终于可以开始集训了Orz (然后上来考试就迟到5min, GG) T1维护队列瞎贪心, 过了大样例交上去一点也不稳...T出翔只拿了5 ...

  8. 2019.3.summary

    emmmm,把以前写的2b总结丢上来吧,不过应该也不会有人看QAQ (注:因为用txt写的,有一些公式打的很随意,放到markdown上公式自动排版,有可能会显示出错误!可在下方留言) 2019.2. ...

  9. 2019暑假绍兴第一中学游记

    Day 0 12:40到了衢州二中,老叶讲了点东西就上路(去绍兴)了. 路上坐大巴坐了四个小时,看$abc__________$写了下他博客的$Argon$主题,然后做了会儿作业. 到了绍兴第一中学旁 ...

最新文章

  1. 两个点击事件共用一个方法_杭州淘宝直播代运营:一个简单的方法,提升直播间封面图点击率!...
  2. HDU5977 Garden of Eden 【FMT】【树形DP】
  3. 项目经理人必须要遵循的14个成功原则
  4. IOS 控件 - Swift 集成 IOS 自带 API 扫描二维码
  5. 【APIO2016】Fireworks【闵可夫斯基和】【凸包向量和】【可并堆】
  6. LoadRunner中Action的迭代次数的设置和运行场景中设置
  7. rsync的介绍及参数详解,配置步骤,工作模式介绍
  8. 如何正确使用日志Log
  9. 南乡子·归梦寄吴樯 [宋] 陆游
  10. Oracle union all和order by一起使用
  11. 用python解析html
  12. axure 发布 主页_【最新实习发布!】滴滴后台/数据产品经理实习生
  13. CountDownLatch、CyclicBarrier、Semaphore的区别
  14. pm2开机启动项目脚本
  15. S2B2C模式有何优势?S2B2C电商系统赋能皮革企业渠道,提升供应链管理效率
  16. 董明珠揭示:未来2年这个行业盈利最大,马总点赞说,又要出富翁
  17. MFA 中文国际音标
  18. Uniapp微信小程序视频全屏播放功能极简实现法
  19. npm i 下载依赖一直报错:git dep preparation failed等
  20. Ubuntu16.04的图形化界面系统安装+NIVIDIA驱动安装-Cuda-Cudnn+教程全(后面安装系统通用)

热门文章

  1. 分享两个比较好用的U盘启动盘工具安装电脑系统必备
  2. Android 生成自己的签名key(releasekey platform shared media networkstack verify等)
  3. 我的Substance Designer 学习笔记02-PBR材质学习理解
  4. 四川麻将必胜攻略笔记(入门篇1)
  5. 第12课 Altium Designer20(AD20)+VESC6.4实战教程:原理图最后验证(北冥有鱼)
  6. 十个最好的免费网络硬盘
  7. 数据分析-numpy-pandas-matplotlib
  8. 前端视角漫谈百度ueditor编辑器前后端分离配置
  9. 浙江计算机专业技术考试大纲,浙江省高校计算机等级考试大纲(三级)
  10. 目标检测—RCNN系列