• dp * 3


    cf 467 C

    从序列中选出 (k) 段连续的 (m) 个数
    最大化总和
    (f_{i, j}) 表示前 (i) 个位置中选出了 (j)
    转移显然

    #include <bits/stdc++.h>
    
    const int N = 5010;
    
    long long f[N][N];
    int n, m, k;
    long long Sum[N];
    
    int main() {
    	std:: cin >> n >> m >> k;
    	for(int i = 1; i <= n; i ++) {
    		std:: cin >> Sum[i];
    		Sum[i] += Sum[i - 1];
    	}
    	for(int i = 1; i <= n; i ++) {
    		for(int j = 1; j <= k; j ++) {
    			if(i - m + 1 > 0) f[i][j] = f[i - m][j - 1] + Sum[i] - Sum[i - m];
    			f[i][j] = std:: max(f[i - 1][j], f[i][j]);
    		}
    	}
    	std:: cout << f[n][k];
    	return 0;
    }
    

    51nod 1354

    给出序列 (a) 和一个整数 (k)
    求子序列的乘积是 (k) 的倍数的方案数

    (f_{i, j}) 表示前 (i) 个数,乘积是 (j) 的方案数
    (f_{i, j} = f_{i - 1, frac{j}{a_{i - 1}}} + f_{i - 1, j})

    由于 (k) 很大
    显然单纯的数组是无法完成的
    这里可以使用 (map), 通过遍历完成

    #include <bits/stdc++.h>
    
    const int N = 1010, Mod = 1e9 + 7;
    
    std:: map <int, int> Map[N];
    int n, k, t;
    int A[N];
    
    int main() {
    	std:: cin >> t;
    	for(; t; t --) {
    		std:: cin >> n >> k;
    		Map[0].clear();
    		for(int i = 1; i <= n; i ++) {
    			std:: cin >> A[i];
    			Map[i].clear();
    		}
    		Map[0][k] = 1;
    		for(int i = 0; i < n; i ++)
    			for(std:: map <int, int> :: iterator it = Map[i].begin(); it != Map[i].end(); it ++) {
    				if(it-> first % A[i + 1] == 0)
    					(Map[i + 1][it-> first / A[i + 1]] += it-> second) %= Mod;
    				(Map[i + 1][it-> first] += it-> second) %= Mod;
    			}
    		std:: cout << Map[n][1] << "
    ";
    	}
    	return 0;
    }
    

    openjudge 6047

    (w imes h) 的蛋糕,切成 (m)
    每刀可以将一块切成两块
    求最小化的最大蛋糕面积
    (f_{i, j, k}) 表示将 (i imes j) 的蛋糕切成 (m) 块时的最小化的最大蛋糕面积
    枚举蛋糕的长和宽以及切成的块数
    固定好后枚举长从哪里分割 (h) 以及分成的块数 (p)
    (f_{i, j, k} = min(f_{i, j, k}, max(f_{h, j, p}, f_{i - h, j, p})))
    同理枚举列
    (f_{i, j, k} = min(f_{i, j, k}, max(f_{i, l, p}, f_{i, j - l, p})))

    #include <bits/stdc++.h>
    
    const int N = 25;
    
    int f[N][N][N];
    
    int main() {
    	int w, h, m;
    	while(std:: cin >> w >> h >> m) {
    		memset(f, 0, sizeof f);
    		if(w == 0 && h == 0 && m == 0) break;
    		for(int i = 1; i <= w; i ++)
    			for(int j = 1; j <= h; j ++)
    				f[i][j][1] = i * j;
    		for(int i = 1; i <= w; i ++)
    			for(int j = 1; j <= h; j ++)
    				for(int k = 2; k <= std:: min(i * j, m); k ++) {
    					f[i][j][k] = (1 << 30);
    					for(int H = 1; H < i; H ++)
    						for(int p = 1; p < k; p ++)
    							f[i][j][k] = std:: min(f[i][j][k], std:: max(f[H][j][p], f[i - H][j][k - p]));
    					for(int L = 1; L < j; L ++)
    						for(int p = 1; p < k; p ++)
    							f[i][j][k] = std:: min(f[i][j][k], std:: max(f[i][L][p], f[i][j - L][k - p]));
    				}
    		std:: cout << f[w][h][m] << "
    ";
    	}
    	return 0;
    }
    
  • 相关阅读:
    开发中的一些总结。。。
    Directory Listing Denied错误
    webservice的一些使用心得。。
    vs2005 sp1 补丁后,不能初始化
    谈C/C++指针精髓
    CString 的函数
    javaScript 中 call 函数的用法说明 & 继承
    条款12: 尽量使用初始化而不要在构造函数里赋值(effectiveC++)
    js日期时间函数(经典+完善+实用)
    学习之路一 记录学习中的手记
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9664416.html
Copyright © 2020-2023  润新知