START
刚开始看到这道题,一眼数据范围,感觉就是三维dp。
但是!!!
第一:longlong很明显是存不下der。但是打高精是不可能的,这辈子都不可能的。于是旁边的dalao告诉我可以用int128诶!!!虽然当时并不知道是什么hhhhh
第二:数组会开不下。细细思考后发现可以开个滚动数组记录前一个枚举的塔的个数的最优解啊,然后总塔数减去两种塔的个数就是最后一种塔的个数呀!!然后就可以愉快的省下了一维啦!!我可真是个小机灵鬼!!不要脸地猛夸自己xixixi
初看这题会感觉比较麻烦,因为三种塔并不是很好处理,但只要细心想就能发现:激光塔对于位置没有什么要求,而干扰塔和放射塔很明显是越靠前所造成的总伤害越高,而单纯的干扰塔并不能对蚂蚁造成伤害,所以最终的方案一定是以一堆放射塔,一堆干扰塔,一堆激光塔的形式存在。(也就是说激光塔的位置应该尽量靠后。)
那么题目变简化成了在n个格子的前i个位置放置干扰塔和放射塔,后n-i个位置放置激光塔所造成的最大伤害。
Code:
1 #include2 #define MAXN 5001 3 using namespace std; 4 __int128 n,r,g,t,b,Ans;//懒于打高精hhhh 5 __int128 ans[MAXN][MAXN];//二维ans[i][j]来表示前i个塔有j个干扰塔,则有i-j个放射塔,n-i个激光塔 6 int read(); 7 void print(__int128 x){ 8 if(x>9) print(x/10); 9 putchar(x%10+'0');//int128是直接输出不了der,所以要这个亚子输出 10 } 11 int main(){ 12 //freopen("antbuster.in","r",stdin); 13 //freopen("antbuster.out","w",stdout); 14 n=read(),r=read(),g=read(),b=read(),t=read();//快读 15 for(int i=1;i<=n;i++) 16 ans[i][0]=(i-1)*g*t+ans[i-1][0];//初始化,若n个点上全部都放上放射塔 17 for(int i=1;i<=n;i++) 18 for(int j=1;j) 19 ans[i][j]=max(ans[i-1][j-1]+(i-j)*g*(t+(j-1)*b),ans[i-1][j]+(i-j-1)*g*(t+j*b)); 20 //共i个点,放j个干扰塔的情况 21 for(int i=0;i<=n;i++) 22 for(int j=0;j<=i;j++) 23 Ans=max(ans[i][j]+r*(n-i)*(t+j*b)+(i-j)*g*(n-i)*(t+j*b),Ans); 24 //n个点上,i个塔已经放置,剩下n-i个塔全部放置激光塔 25 print(Ans);//输出 26 return 0; 27 } 28 int read()//快读 29 { 30 int x=0,k=1;char ch=' '; 31 while(!isdigit(ch)){ 32 ch=getchar(); 33 if(ch=='-') k=-1; 34 } 35 while(isdigit(ch)){ 36 x=x*10+ch-'0'; 37 ch=getchar(); 38 } 39 return k*x; 40 }