• 洛谷-P2198 杀蚂蚁


    Solution

    大致感受一下,我们就可以发现似乎激光塔一定要放在最末尾才能最大化一个激光塔给蚂蚁的伤害,所以所有的激光塔我们强制全部放在最末尾.然后呢,我们需要把前面的多余空位合理安排给放射塔和激光塔,这个过程可以用DP来解决,大致就是设F[i][j] 表示前i+j格空位放置i座干扰塔,j座放射塔给蚂蚁带来的最大伤害.没了.

    f[i][j]=max(f[i - 1][j] + g * j * b * k,f[i][j - 1] + g * (b * i + t) * k)

    好,但是由于数据实在太大,所以要加上复杂的高精度,嗯,大概就是要写高精乘高精,高精乘低精,高精减低精,高精加高精,高精加低精,高精度数大小比较等等,不过没事,也就几行...

    #include<bits/stdc++.h>
    using namespace std;
    const int mo = 100000000, maxn = 1055;
    struct node{
    	long long w[30];
    	inline void operator += (long long x){
    		w[1] += x; int i = 1;
    		while (w[i] >= mo) w[i] -= mo, ++ w[++i];
    		if (i > w[0]) w[0] = i;
    	}
    };
    
    inline node operator + (node a, node b){
    	for (int i = 1; i <= b.w[0]; ++i) a.w[i] += b.w[i];
    	a.w[0] = max(a.w[0], b.w[0]);
    	for (int i = 1; i <= a.w[0]; ++i) if (a.w[i] >= mo) a.w[i] -= mo, ++ a.w[i + 1];
    	if (a.w[a.w[0] + 1]) ++ a.w[0];
    	return a;
    }
    
    inline node operator * (node a, node b){
    	node c; memset(c.w, 0, sizeof(c.w)); 
    	for (int i = 1; i <= a.w[0]; ++i) 
    	for (int j = 1; j <= b.w[0]; ++j) c.w[i + j - 1] += a.w[i] * b.w[j];
    	c.w[0] = a.w[0] + b.w[0] - 1;
    	for (int i = 1; i <= c.w[0]; ++i) if (c.w[i] >= mo) c.w[i + 1] += c.w[i] / mo, c.w[i] %= mo;
    	while (c.w[c.w[0] + 1]) ++ c.w[0];
    	return c;
    }
    
    inline node operator * (node a, long long x){
    	for (int i = 1; i <= a.w[0]; ++i) a.w[i] *= x;
    	for (int i = 1; i <= a.w[0]; ++i) if (a.w[i] >= mo) a.w[i + 1] += a.w[i]/mo, a.w[i] %= mo;
    	if (a.w[a.w[0] + 1]) ++ a.w[0];
    	return a;
    }
    
    inline node operator - (node a, node b){
    	for (int i = 1; i <= b.w[0]; ++i) a.w[i] -= b.w[i];
    	for (int i = 1; i <= a.w[0]; ++i) if (a.w[i] < 0) a.w[i] += mo, -- a.w[i + 1];
    	while (a.w[0] > 0 && !a.w[a.w[0]]) -- a.w[0];
    	return a;
    }
    
    inline bool operator < (node a, node b){
    	if (a.w[0] != b.w[0]) return a.w[0] < b.w[0];
    	for (int i = a.w[0]; i; --i) if (a.w[i] != b.w[i]) return a.w[i] < b.w[i];
    	return false;
    }
    
    inline void read(node &a){
    	char s[300]; memset(a.w, 0, sizeof(a.w));
    	scanf("%s", s); int m = strlen(s);
    	int x,j,i;
    	for (x = 0, j = 1, i = m - 1; ~i; --i, j *= 10){
    		if (j == mo) j = 1, a.w[++a.w[0]] = x, x = 0;
    		x += (s[i] - '0') * j;
    	}
    	if (x) a.w[++ a.w[0]] = x;
    	if (!a.w[0]) a.w[0] = 1;
    }
    
    inline void print(node a){
    	printf("%lld", a.w[a.w[0]]);
    	for (int i = a.w[0] - 1; i > 0; --i){
    		for (int j = 10; j < mo; j *= 10) if (a.w[i] < j) putchar('0');
    		printf("%lld", a.w[i]);
    	}
    	puts("");
    }
    
    long long n;
    node  r, g, b, t;
    node f[maxn][maxn], ans; 
    
    inline node max(node a, node b){
    	return a < b ? b : a;
    }
    
    int main(){
    	scanf("%lld", &n);
    	read(r); read(g); read(b); read(t);
    	//return 0;
    	for (long long i = 1; i <= n; ++i) f[0][i] = f[0][i - 1] + g * t * (n - i);	
    	for (long long i = 1; i < n; ++i) 
    	for (long long j = 1, k; k = n - i - j; ++j)
    	f[i][j] = max(f[i - 1][j] + g * j * b * k, 
    	// b * k Ϊ¼ÓÁËÒ»×ù¸ÉÈÅËþºó¶à³öµÄʱ¼ä, g * j Ϊj×ù·ÅÉäËþµÄÉ˺¦. 
    				  f[i][j - 1] + g * (b * i + t) * k);
    	// Õâ×ùмӵķÅÉäËþÔì³ÉµÄÉ˺¦ÊÇ g, ´Ëʱÿ¸ñ³ÖÐøµÄʱ¼äΪ i * b + t, ¹²ÓÐk¸ñ,ÄÇô
    	// É˺¦Îª g * (i * b + t) * k
    	for (long long i = 0; i <= n; ++i) 
    	for (long long j = 0; j <= n - i; ++j) {
    		long long k = n - i - j; if (k < 0) continue;
    		ans = max(ans, f[i][j] + (t + b * i) * k * r);
    	}
    	print(ans);				
    	return 0;
    }
    /*
    400 2147483647 2147483647 2147483647 1000
    */
  • 相关阅读:
    重置SQLSERVER表的自增列,让自增列重新计数
    【PLM】【PDM】60页PPT终于说清了PDM和PLM的区别;智造时代,PLM系统10大应用趋势!
    数据库设计规范
    不要听吹牛逼什么前端MVVM框架就是好,其实都是一帮没学好分层设计的搞出来的,让你彻底看清前端MVVM的本质
    SQL数据库日志清理
    1.3、安装MySQL、MySQLdb、Pycharm和其他软件
    1.2.2.3、Django虚拟目录作用以及文件说明
    nginx设置图片防盗链和白名单
    php-5.5.7升级,编译配置方法
    mysql函数CONCAT_WS()比CONCAT()更方便
  • 原文地址:https://www.cnblogs.com/juruohx/p/7779618.html
Copyright © 2020-2023  润新知