棋盘切割 DP POJ 1191

把方差公式先变形为 σ2 = (1/n)∑xi2-xa2

xa为平均值。

由于要求标准差最小,只需方差最小,平均值都是一样的,n也是一样的,这样原问题就变为求这n快小棋盘总分的平方和最小

考虑左上角为(x1,y1),右上角为(x2,y2)的棋盘,设该棋盘切割K次后得到的K+1块矩形的总分平方和最小值为d[k,x1,y1,x2,y2]。该棋盘的总分平方和为

s[x1,y1,x2,y2].则它可以沿着横线切,也可以沿着竖线切,然后选一块继续切(这里可以用递归完成)

状态转移方程为d[k,x1,y1,x2,y2] =  min{

min{ d[k-1,x1,y1,a,y2] + s[a+1,y1,x2,y2] , d[k-1,a+1,y1,x2,y2] + s[x1,y1,a,y2] },    (x1 <= a < x2)

min{ d[k-1,x1,y1,x2,b] + s[x1,b+1,x2,y2] , d[k-1,x1,b+1,x2,y2] + s[x1,y1,x2,b] }  (y1 <= b < y2)

}

贴代码:

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #define N 9
 5 #define min(a,b) a<b?a:b
 6 #define INF 100000000
 7 int n;
 8 int map[N][N];
 9 int presum[N][N];
10 int d[16][N][N][N][N];//用d[k][x1][y1][x2][y2]表示左上角为(x1,y1)
11 //右下角为(x2,y2)的棋盘切成了k+1块时最小的总分平方和值
12 void presolve()
13 {
14     //预处理,算出所有左上角为(1,1)的所有矩阵元素和
15     int i,j;
16     for(i=0; i<=N; ++i)
17         presum[0][i] = 0,presum[i][0] = 0;
18     for(i=1; i<N; ++i)
19     {
20         int rowsum = 0;
21         for(j=1; j<N; ++j)
22         {
23             scanf("%d",&map[i][j]);
24             rowsum += map[i][j];
25             presum[i][j] = presum[i-1][j] + rowsum;
26         }
27     }
28 }
29 int rectSquare(int x1,int y1,int x2,int y2)
30 {
31     //计算左上角为(x1,y1),右下角为(x2,y2)的棋盘的总分平方和
32     int ret = presum[x2][y2] -presum[x1-1][y2] -presum[x2][y1-1] +presum[x1-1][y1-1];
33     return ret*ret;
34 }
35 //DP程序
36 int DP(int k,int x1,int y1,int x2,int y2)
37 {
38     int t,c,e;
39     int MIN = INF;//用来求最后的d[k][x1][y1][x2][y2]
40     if(d[k][x1][y1][x2][y2] != -1)//记忆化搜索???已经求过了,不再求,直接用
41         return d[k][x1][y1][x2][y2];
42     if(k == 0)//切0刀,不就是该棋盘了吗?最小值也是该棋盘的总分平方和,边界条件
43         return d[k][x1][y1][x2][y2]=rectSquare(x1,y1,x2,y2);
44     for(int a = x1; a < x2; ++a)
45     {
46         //横着切成了两块
47         c = rectSquare(a+1,y1,x2,y2);
48         e = rectSquare(x1,y1,a,y2);
49         t = min(DP(k-1,x1,y1,a,y2) + c,DP(k-1,a+1,y1,x2,y2) + e);//选取一块继续切割
50         MIN = min(MIN,t);
51     }
52     for(int b = y1; b < y2; ++b)
53     {
54         //竖着切成了两块
55         c = rectSquare(x1,b+1,x2,y2);
56         e = rectSquare(x1,y1,x2,b);
57         t= min(DP(k-1,x1,y1,x2,b)+c,DP(k-1,x1,b+1,x2,y2)+e);//选取一块继续切割
58         MIN = min(MIN,t);
59     }
60     d[k][x1][y1][x2][y2] = MIN;//所有的情况都考虑完后,所得就是该最小值
61 //    printf("d[%d][%d][%d][%d][%d] = %d\n",k,x1,y1,x2,y2,d[k][x1][y1][x2][y2]);
62     return MIN;
63 }
64 int main()
65 {
66 //    freopen("in.cpp","r",stdin);
67     scanf("%d",&n);
68     presolve();
69     memset(d,-1,sizeof(d));
70     int sumsquare = DP(n-1,1,1,8,8);
71     double f = n*sumsquare - presum[8][8]*presum[8][8];
72     f = sqrt(f)/n;
73     printf("%.3f\n",f);
74 //    printf("%d\n",0x7fffffff);
75     return 0;
76 }
注意:
用double,然后用%.3lf WA 用%.3fAC 在DP时min的初始值赋为10^7WA 赋为10^8AC 这点我还比较想得通,棋盘最大的总分和为6400,最大的平方和即为6400^6400,为40960000 你赋的min值至少应该大于这个数,否则就不对了,所以10^7可能会错 我中间赋过一个0x7fffffff,竟然导致出现了负数,怎么会啊。。。。。不了解
补充:我现在理解了为什么出现负数,因为0x7fffffff是最大的整数数了,再加就溢出了,成为负的了·····

转载于:https://www.cnblogs.com/allh123/archive/2013/05/05/3061122.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421812.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lucene,lucene.net学习教程

lucene学习教程 1.1 什么是lucene Lucene是一个全文搜索框架&#xff0c;而不是应用产品。因此它并不像www.baidu.com 或者google Desktop那么拿来就能用&#xff0c;它只是提供了一种工具让你能实现这些产品。 2 lucene的工作方式 lucene提供的服务实际包含两部分&#xf…

(JAVA)正则表达式

正则表达式的常见规则 1.字符类[abc]&#xff1a;字符必须是abc其中一个[a-z]&#xff1a;字符必须是小写字母[A-Z]&#xff1a;字符必须是大写字母[a-zA-Z]&#xff1a;字符必须是字母[^abc]&#xff1a;字符不能是abc其中一个[^a-z]&#xff1a;字符不能是小写字母[^a-zA-Z]:…

巧用“傍术”选择陈列点

割箱 陈列 是一种将包装纸箱割斜角&#xff0c;以露出商品的 陈列 方式&#xff0c;广泛应用在包袋食品及小百货商品。  商超内的位置很多&#xff0c;选择什么样的位置 陈列 产品能够起到最好的效果呢&#xff1f;  首先是要找视觉效果尽可能好的地方。消费者进入商场第一…

(JAVA) * 使用正则表达式,给字符串排序 * 使用数组排序

package com.book.lite;import java.util.Arrays;/*** author zhangyu* date 2021年08月19日 10:49 下午* 使用正则表达式&#xff0c;给字符串排序* 使用数组排序*/ public class RegexDemo1 {public static void main(String[] args) {test();}public static void test(){Str…

python 使用 pip 安装第三方库 导入不成功

本文是什么意思呢&#xff1f; 就是你需要使用一些库安装老师或者网上说的 通过pip 安装下载了第三方库&#xff0c;但是使用 import xxx from xxx import xx &#xff0c;pycharm ide 导入的下面还有红色波浪线&#xff0c;导入不成功。 这是什么原因&#xff1f; 这是pyc…

LLVM每日谈之十三 使用LLVM自带的PASS

作者&#xff1a;snsn1984 PS&#xff1a;最近一段时间&#xff0c;投入在LLVM上的时间有些减少。差点把对它的研究断掉&#xff0c;今天开始继续。对LLVM的研究需要很长一段时间的坚持不懈才可以彻底搞明白。 前面已经介绍过如何写自己的PASS&#xff0c;并且也针对一个简单的…

(JAVA)Math类

package com.book.lite;import java.util.regex.Matcher;/*** author zhangyu* date 2021年08月19日 11:34 下午* 1.绝对值*/ public class MathDemo {public static void main(String[] args) {System.out.println(methon_1());System.out.println(methon_2());System.out.pri…

Android学习笔记-判断手机外部存储是否可读写

通过调用Environment的getExternalStorageState()方法来判断外部存储的状态: /* 查检外部存储读取与写入功能是否可用 */ public boolean isExternalStorageWritable() {String state Environment.getExternalStorageState();if (Environment.MEDIA_MOUNTED.equals(state)) {r…

寄存器指令MIPS 寄存器介绍

之前朋友几篇文章介绍了改寄存器指令的文章. 关联文章的地址 MIPS有32个通用寄存器&#xff08;$0-$31&#xff09;&#xff0c;各寄存器的功能及汇编程序中应用约定如下&#xff1a; 下表描述32个通用寄存器的别名和用处 REGISTER NAME USAGE $0 $zero 常量0(constant va…

(JAVA)Random类

package com.book.lite;import java.util.Random;/*** author zhangyu* date 2021年08月19日 11:57 下午* Math.random()获取随机数&#xff0c;底层调用Random类* Random类* 1.构造方法* 2.nextInt(int n )*/public class RandomDemo {public static void main(String[] args)…

SIFT算法

介绍这个算法的网上的博客很多&#xff0c;这个百度一下就有很多篇&#xff0c;我写一下我的认识。 前面考虑的一个图像的特征点是角点&#xff0c;这边提出了&#xff0c;图像的特征点可以是一个斑点&#xff0c;就像 明显的就是部分向日葵的原型就是一个特征&#xff0c;而这…

(JAVA)超大整数运算

package com.book.lite;import java.math.BigInteger;/*** author zhangyu* date 2021年08月21日 4:27 下午* Biginterger类&#xff0c;超大数的四则运算*/ public class BigIntegerDemo {public static void main(String[] args) {methon_3();}public static BigInteger meth…

PHP中过滤数组中的元素

演示使用自定义函数删除数组中的偶数元素。 <?php function myfunc(&$arr){//自定义一个过滤函数$jcount($arr);for($i0;$i<$j;$i){if($arr[$i]%20)unset($arr[$i]);} }$arrarray(23,14,37,263,244,379,100,153,150);//定义一个数组 echo 数组进行过滤之前的信息&am…