zoukankan      html  css  js  c++  java
  • 浙江十套

    产品报告

    对于B[i]降序排列是显而易见的,因为将最大的冷却时间放在最后,才会是最优的(本来写的贪心, 结果和zs大佬交流后发现我题意立即错了)。

    使用DP的原因是冷却时间在第一个机器和在第二个机器的分配不同,导致最后的答案不同。

    (f[i][j]) 表示第一个机器在处理前 (i) 个产品花费j时间时,总的时间花费的最小值。((f[i][j]) 包括了最后的冷却时间) , 所以第二个机器的花费可以算出来,总的
    花费就是上面两个取最小值。

    对于第一台机子:(f[i][j] = min( f[i][j], max(f[i - 1][j - a[i]],j + b[i] )), (如果上一个的冷却时间超级长,就是第一个,否则是第二个)对于第二台机子 : (f[i][j] = min ( f[i][j], max( f[i - 1][j] , sum[i] - j + b[i]))(i) 位不由第一台机子处理因此是f[i - 1][j],剩下的由第二台处理)。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define LOCAL
    const int maxn = 210;
    int n;
    int sum[maxn], f[maxn][maxn * maxn];
    int max (int x, int y) {
    	return x > y ? x : y;
    }
    
    int min (int x, int y) {
    	return x < y ? x : y;
    }
    
    struct Product {
    	int a, b;
    };
    Product pro[maxn];
    
    bool cmp (Product pro1, Product pro2) {
    	return pro1.b > pro2.b;
    }
    
    inline void DP() {
    	for (int i = 0; i <= n; ++ i)
    		for (int j = 0; j <= maxn * maxn - 1; ++ j)
    			f[i][j] = maxn * maxn + 10;
    	f[0][0] = 0;
    
    	for (int i = 1; i <= n; ++ i) {
    		for (int j = 0; j <= sum[i]; ++ j) {
    			if (j >= pro[i].a) {
    				f[i][j] = min(f[i][j], max(f[i - 1][j - pro[i].a], j + pro[i].b));
    			}
    			if (sum[i] - j + pro[i].b >= 0) {
    				f[i][j] = min(f[i][j], max(f[i - 1][j], sum[i] - j + pro[i].b));
    			}
    		}
    	}
    	
    	int ans = 0x7fffffff - 1;
    	for (int i = 1; i <= sum[n]; ++ i) {
    		ans = min(f[n][i], ans);
    	}
    	printf("%d
    ", ans);
    }
    
    inline void init() {
    #ifdef LOCAL
    	freopen("sort.in","r",stdin);
    	freopen("sort.out","w",stdout);
    #endif
    	scanf("%d", &n);
    	for (int i = 1; i <= n; ++ i) {
    		scanf("%d%d", &pro[i].a, &pro[i].b);
    	}
    	std::sort(pro + 1, pro + n + 1, cmp);
    	for (int i = 1; i <= n; ++ i)
    		sum[i] = sum[i - 1] + pro[i].a;
    }
    
    int main() {
    	init();
    	DP();
    	return 0;
    }
    
    

    分球

    这道题非常简单,要么用数学方法算一下排列组合,要么就自己打一个递推,只是需要用高精度。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    const int maxn = 110;
    const int maxm = 100;
    int n,m;
    struct Bignum {
    	int dig[maxn];
    	int len;
    	Bignum() {
    		memset(dig,0,sizeof(dig));
    		len = 1;
    	}
    };
    Bignum F[maxn][maxn];
    inline Bignum Plus(Bignum a, Bignum b) {
    	for (int i = 1; i <= b.len; ++ i) {
    		a.dig[i] += b.dig[i];	
    	}
    	for (int i = 1; i <= max(a.len,b.len) + 1; ++ i) {
    		a.dig[i + 1] += a.dig[i] / 10;
    		a.dig[i] %= 10;
    	}
    	int k = maxm - 1;
    	while(a.dig[k] == 0) k --;
    	a.len = k;
    	return a;
    }
    
    inline Bignum Mul(Bignum a, int b) {
    	for (int i = 1; i <= a.len; ++ i) {
    		a.dig[i] *= b;
    	}
    	for (int i = 1; i <= maxm - 3; ++ i) {
    		a.dig[i + 1] += a.dig[i] / 10;
    		a.dig[i] %= 10;
    	}
    	int k = maxm - 1;
    	while(a.dig[k] == 0) k --;
    	a.len = k;
    	return a;
    }
    
    inline void Print(Bignum a) {
    	for (int i = a.len; i >= 1; -- i) {
    		cout << a.dig[i];
    	}
    	putchar('
    ');
    }
    
    inline void solve() {
    	for (int i = 1; i <= maxn - 1; ++ i) {
    		for (int j = 1; j <= maxn - 1; ++ j) {
    			if ( i == j ) F[i][j].dig[1] = 1, F[i][j].len = 1;
    			else if ( i > j ) {
    				F[i][j] = Plus(Mul(F[i - 1][j],j),F[i - 1][j - 1]);
    			}
    		}
    	}
    }
    
    int main() {
    	freopen("ball.in","r",stdin);
    	freopen("ball.out","w",stdout);
    	int N,M;
    	F[0][0].dig[1] = 1, F[0][0].len = 1;
    	solve();
    	while(cin >> N >> M) {
    		if (N < M) cout << 0 << endl;
    		else if (N == M) cout << 1 << endl;
    		else Print(F[N][M]);
    	}
    
    }
    

    地图

    dfs标记联通块

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    const int maxn = 1010;
    bool map[maxn][maxn];
    int ans = 0;
    int n,m;
    
    int dx[5] = {0,1,-1,0,0};
    int dy[5] = {0,0,0,1,-1};
    
    inline void DFS(int x, int y) {
    	map[x][y] = 0;
    	for (int i = 1; i <= 4; ++ i) {
    		int nowx = x + dx[i];
    		int nowy = y + dy[i];
    		if (map[nowx][nowy]){
    			DFS(nowx,nowy);
    		}
    	}
    }
    
    int main() {
    	freopen("map.in","r",stdin);
    	freopen("map.out","w",stdout);
    	cin >> n >> m;
    	for (int i = 1; i <= n ; ++ i) {
    		for (int j = 1; j <= m; ++ j) {
    			char x;
    			cin >> x;
    			if(x == 'X') map[i][j] = 1;
    			else map[i][j] = 0;
    		}
    	}
    
    	for (int i = 1; i <= n; ++ i) {
    		for (int j = 1; j <= m; ++ j) {
    			if(map[i][j]) {
    				DFS(i,j);
    				ans ++;
    			}
    		}
    	}
    	cout << ans;
    }
    

    坐标变换

    这道题要用到Graham的一点知识,还有关于凸包的一点小小的常识,用dp求出每一个点,就OK了。新建的n + 1 这个点是为了保证最后围成封闭。

    然后感谢lcc大佬的帮助。

    #include <cstdio>
    #include <algorithm>
    #define LOCAL
    const int maxn = 105;
    int f[maxn][maxn];
    
    struct Point {
    	int x, y;
    };
    Point map[maxn];
    
    int n, ans = 0;
    
    int max (int a, int b) {
    	return a > b ? a : b;
    }
    
    bool cmp (Point a, Point b) {
    	return ((double) a.y / a.x) < ((double) b.y / b.x);
    }
    
    inline bool check(int a, int b, int c) {
    	int tmp = 0;
    	tmp += map[a].x * map[b].y;
    	tmp += map[a].y * map[c].x;
    	tmp += map[b].x * map[c].y;
    	tmp -= map[b].y * map[c].x;
    	tmp -= map[c].y * map[a].x;
    	tmp -= map[b].x * map[a].y;
    	return tmp < 0; 
    }
    
    inline void init() {
    #ifdef LOCAL
    	freopen("polygon.in","r",stdin);
    	freopen("polygon.out","w",stdout);
    #endif
    	scanf("%d", &n);
    	for (int i = 1; i <= n; ++ i) {
    		scanf("%d%d", &map[i].x, &map[i].y);
    		f[i][0] = 1;
    	}
    	std::sort(map + 1, map + n + 1, cmp);
    	map[0].x = 0, map[0].y = 0;
    	map[n + 1].x = map[n + 1].y = 0;
    }
    
    inline void DP() {
    	for (int i = 2; i <= n + 1; ++ i) {
    		for (int j = 1; j < i; ++ j) {
    			f[i][j] = 0;
    			for (int k = 0; k < j; ++ k) {
    				if (check(i, j, k)) {
    					f[i][j] = max(f[i][j], f[j][k] + 1);
    				}
    			}
    		}
    	}
    	ans = 0;
    	for (int i = 1; i <= n; ++ i) {
    		ans = max(ans, f[n + 1][i]);
    	}
    	printf("%d
    ", ans);
    }
    
    int main() {
    	init();
    	DP();
    }
    
  • 相关阅读:
    设计改进ls代码实现更多功能
    20181328 《网络攻防》 EXP5 信息收集与漏洞扫描
    Socket 实验代码
    冲刺第一天——安装熟悉所使用的软件及其环境配置
    20181328 《网络对抗技术》Exp3 免杀原理与实践
    20181328 网络攻防实验一 PC平台逆向破解
    20181328 网络攻防实验一 PC平台逆向破解(最终版)
    20181328祝维卿——Exp2后门原理与实践
    设计实现ls功能
    Sql 2008 : 数据库分文件组(指定磁盘), 映射分区表使用不同的文件组详解(阻止保存要求重新创建表的更改?)
  • 原文地址:https://www.cnblogs.com/Alessandro/p/9147129.html
Copyright © 2011-2022 走看看