• [BZOJ 1048] [HAOI2007] 分割矩阵 【记忆化搜索】


    题目链接:BZOJ - 1048

    题目分析

    感觉这种分割矩阵之类的题目很多都是这样子的。

    方差中用到的平均数是可以直接算出来的,然后记忆化搜索 Solve(x, xx, y, yy, k) 表示横坐标范围 [x, xx], 纵坐标范围 [y, yy] 的矩阵切成 k 块的最小 sigma((Vi - Ave)^2) 。

    然后再递归将矩阵分得更小,直到 k 为 1 的时候直接返回相应的值。

    代码

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    
    using namespace std;
    
    const int MaxN = 15 + 5, MaxT = 15 + 5;
    
    int n, m, t, Num;
    int Sum[MaxN][MaxN];
    
    typedef double DB;
    
    const DB INF = 999999999;
    
    DB Ave;
    DB f[MaxN][MaxN][MaxN][MaxN][MaxT];
    
    DB Get(int x, int y, int xx, int yy) {
    	return (DB)(Sum[xx][yy] - Sum[x - 1][yy] - Sum[xx][y - 1] + Sum[x - 1][y - 1]);
    }
    
    inline DB Sqr(DB x) {return x * x;} 
    inline DB gmin(DB a, DB b) {return a < b ? a : b;}
    
    DB Solve(int x, int xx, int y, int yy, int k) {
    	if (f[x][xx][y][yy][k] != -1) return f[x][xx][y][yy][k];
    	if (k == 1) return f[x][xx][y][yy][k] = Sqr(Get(x, y, xx, yy) - Ave);
    	DB ret = INF;
    	for (int i = x; i <= xx - 1; ++i)
    		for (int j = 1; j <= k - 1; ++j)
    			ret = gmin(ret, Solve(x, i, y, yy, j) + Solve(i + 1, xx, y, yy, k - j));
    	for (int i = y; i <= yy - 1; ++i) 
    		for (int j = 1; j <= k - 1; ++j) 
    			ret = gmin(ret, Solve(x, xx, y, i, j) + Solve(x, xx, i + 1, yy, k - j));
    	return f[x][xx][y][yy][k] = ret; 
    }
    
    int main() 
    {
    	scanf("%d%d%d", &n, &m, &t);
    	for (int i = 1; i <= n; ++i)
    		for (int j = i; j <= n; ++j)
    			for (int p = 1; p <= m; ++p)
    				for (int q = p; q <= m; ++q)
    					for (int o = 1; o <= t; ++o) 
    						f[i][j][p][q][o] = -1;
    	memset(Sum, 0, sizeof(Sum));
    	for (int i = 1; i <= n; ++i) {
    		for (int j = 1; j <= m; ++j) {
    			scanf("%d", &Num);
    			Sum[i][j] = Sum[i][j - 1] + Sum[i - 1][j] - Sum[i - 1][j - 1] + Num;
    		}
    	}
    	Ave = (DB)Sum[n][m] / (DB)t;
    	Solve(1, n, 1, m, t);
    	printf("%.2lf
    ", sqrt(f[1][n][1][m][t] / t));
    	return 0;
    }
    

      

  • 相关阅读:
    ROM定制开发教程-Android adb命令用法与实例解析
    Android内存优化—dumpsys meminfo详解
    adb命令查看手机应用内存使用情况
    【特征检测】BRISK特征提取算法
    焦虑症
    基于Lua的游戏服务端框架简介
    流量
    学习React Native必看的几个开源项目
    那些离开私企进入国企的人,现在都过得怎么样了?
    分布式系统中有关一致性的理解
  • 原文地址:https://www.cnblogs.com/JoeFan/p/4263820.html
Copyright © 2020-2023  润新知