小奇的矩阵(动态规划

【题目 背景】

小奇总是在数学课上思考奇怪的问题。

【问题描述】

给定一个 n*m 的矩阵, 矩阵中的每个元素 aij 为正整数。

接下来规定

1. 合法的路径初始从矩阵左上角出发, 每次只能向右或向下走, 终点为右下 角。

2. 路径经过的 n+m-1 个格子中的元素为 A1, A2…A(n+m-1) , Aavg 为 Ai 的平 均数, 路径的 V 值为(n+m-1) *∑ (Ai-Aavg) ^2 (1<=i<=n+m-1)

求 V 值最小的合法路径, 输出 V 值即可, 有多组测试数据。

【输入格式】

第一行包含一个正整数 T, 表示数据组数。

对于每组数据: 第一行包含两个正整数 n 和 m, 表示矩阵的行数和列数。

接下来 n 行, 每行 m 个正整数 aij, 描述这个矩阵。

【输出格式】

对于每次询问, 输出一行一个整数表示要求的结果

【样例输入】

12 2 1 2 3 4

【样例输出】

14

【数据范围】

对于 30%的数据 n<=10, m<=10

有另外 40%的数据 n<=15 m<=15, 矩阵中的元素不大于 5

对于100%的数据 T<=5, n<=30, m<=30, 矩阵中的元素不大于 30



下面全都是自己的话

又是一道小奇系列的题,感觉要被可爱的小奇洗脑了(麻烦你作为一只小猫不要再数学课上胡思乱想好不好啦)

首先一看这个神秘的式子,初中学历以上的OIer们在内心尖叫:我知道!这是在求方差!

可是为什么要求平均数而最后的结果还是整数啊??是不是把小数点全抹掉四舍五入啊??会不会爆精度啊??NOIP好像不让用long double 来着...

别急,我们先看数据规模,并不是很大,熟悉动态规划的同学应该都会直接想到DP了。但是——我要走到终点才能知道平均数是多少啊,这个后效性阻断了了我的AC之路。。

所以还是回到式子上,考虑一下化简。

观察到式子的一开始乘了一个(n+m-1),化简后居然把所有所有的分母都消去了(!)

最终化简出来大概是这样

(n+m-1)*(a1^2 + a2^2 + a3^2 +...+ai^2)-(a1+a2+a3+...+ai)^2

啊哈,原来根本不用什么double型嘛,结果都是整数的。

那我们接下来考虑DP方程怎么写吧,要怎么表示每一个坐标的状态呢??
......
......
......
......
......
f[i][j][.....??
......
......

同样的Sigma(ai)是可以表示不同的Sigma(ai^2)的(!)

所以我们的数组f[i][j][k],前两维就表示走到的位置(i,j)咯,然后k表示此时的Sigma(ai)(就是刚刚那个式子后面的部分除去平方),这个状态下式子的前半部分(n+m-1)*(a1^2 + a2^2 + a3^2 +...+ai^2) 最小是多少(!)太好了这样就可以转移了,既满足最优子结构的性质,又满足无后效性。

相信大家都能自己写出转移方程了吧(实在不行就看代码吧)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6
 7 #define For(i,a,b) for(register int i=a;i<=b;++i)
 8 #define Dwn(i,a,b) for(register int i=a;i>=b;--i)
 9 #define Re register
10 #define Pn putchar(‘\n‘)
11 #define llg long long
12 using namespace std;
13 const int N=32;
14 int n,m,a[N][N],nxm,Mx=0;
15 llg f[N][N][2000];
16 inline void read(int &v){
17     v=0;
18     char c=getchar();
19     while(c<‘0‘||c>‘9‘)c=getchar();
20     while(c>=‘0‘&&c<=‘9‘)v=v*10+c-‘0‘,c=getchar();
21 }
22 void write(llg x){
23     if(x>9)write(x/10);
24     int xx=x%10;
25     putchar(xx+‘0‘);
26 }
27 int main(){
28     freopen("matrix.in","r",stdin);
29     freopen("matrix.out","w",stdout);
30     int T; read(T);
31     while(T--){
32         read(n); read(m);
33         nxm=n+m-1;
34         For(i,1,n) For(j,1,m)read(a[i][j]);
35
36         memset(f,-1,sizeof(f));
37
38         f[1][1][a[1][1]]=nxm*a[1][1]*a[1][1];
39         Mx=a[1][1];
40
41         For(i,1,n) For(j,1,m){
42             if(i==1&&j==1)continue;
43             int adx=a[i][j];
44             int pMx=Mx;
45             Dwn(k,pMx,1){
46                 llg fx;
47
48                 fx=f[i-1][j][k];   // I walk to you from your top side
49                 if(fx!=-1){
50                     Mx=max(Mx,k+adx);
51
52                     if(f[i][j][k+adx]==-1){
53                         f[i][j][k+adx]=fx+nxm*adx*adx;
54                     }else{
55                         f[i][j][k+adx]=min(f[i][j][k+adx],fx+nxm*adx*adx);
56                     }
57                 }
58
59                 fx=f[i][j-1][k];  // I walk to you from your left side
60                 if(fx!=-1){
61                     Mx=max(Mx,k+adx);
62
63                     if(f[i][j][k+adx]==-1){
64                         f[i][j][k+adx]=fx+nxm*adx*adx;
65                     }else{
66                         f[i][j][k+adx]=min(f[i][j][k+adx],fx+nxm*adx*adx);
67                     }
68                 }
69
70             }
71
72         }
73
74         llg ans=1e18;
75         For(i,1,Mx) if(f[n][m][i]!=-1){
76             ans=min(ans,f[n][m][i]-i*i);
77         }
78         write(ans); Pn;
79     }
80     fclose(stdin); fclose(stdout);
81     return 0;
82 }

希望能得到支持(推荐)

 

原文地址:https://www.cnblogs.com/HLAUV/p/9893323.html

时间: 2024-07-29 04:08:30

小奇的矩阵(动态规划的相关文章

[Scoi2015]小凸玩矩阵

bzoj 4443: [Scoi2015]小凸玩矩阵 http://www.lydsy.com/JudgeOnline/problem.php?id=4443 Time Limit: 10 Sec  Memory Limit: 128 MB Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少. Input 第一行给出三个整数N,M,K 接下来N

LibreOJ #2006. 「SCOI2015」小凸玩矩阵

二次联通门 : LibreOJ #2006. 「SCOI2015」小凸玩矩阵 /* LibreOJ #2006. 「SCOI2015」小凸玩矩阵 本来以为是道数据结构题 后来想了想发现不可做 就考虑二分dp判断 推方程推不出来 就考虑用网络流判断了 二分出一个数 将小于这个数的位置的点编号 每行的可行点与下一行可行的点连边 后一边最大流判断可选出的数的个数是否符合要求即可 */ #include <cstdio> #include <iostream> #include <q

LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

#2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 小凸和小方是好朋友,小方给小凸一个 N×M N \times MN×M(N≤M N \leq MN≤M)的矩阵 A AA,要求小凸从其中选出 N NN 个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的 N NN 个数中第 K KK 大的数字的最小值是多少. 输入格式 第一行给出三个整数

【BZOJ-4548&amp;3658】小奇的糖果&amp;Jabberwocky 双向链表 + 树状数组

4548: 小奇的糖果 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 103  Solved: 47[Submit][Status][Discuss] Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾 起多少糖果,使得获得的糖果并不包含所有的颜色. Input 包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数. 接下来 T 组测试数据,对于每组测试数据,第

【NOIP模拟赛】小奇挖矿 2

[题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎. [问题描述] 现在有m+1个星球,从左到右标号为0到m,小奇最初在0号星球. 有n处矿体,第i处矿体有ai单位原矿,在第bi个星球上. 由于飞船使用的是老式的跳跃引擎,每次它只能从第x号星球移动到第x+4号星球或x+7号星球.每到一个星球,小奇会采走该星球上所有的原矿,求小奇能采到的最大原矿数量. 注意,小奇不必最终到达m号星球. [输入格式] 第一行2个整数n,m

4711: 小奇挖矿

4711: 小奇挖矿 Description [题目背景] 小奇在喵星系使用了无限非概率驱动的采矿机,以至于在所有星球上都采出了一些矿石,现在它准备建一些矿石仓 库并把矿石运到各个仓库里. [问题描述] 喵星系有n个星球,标号为1到n,星球以及星球间的航线形成一棵树.所有星球间的双向航线的长度都为1.小奇要 在若干个星球建矿石仓库,设立每个仓库的费用为K.对于未设立矿石仓库的星球,设其到一个仓库的距离为i,则 将矿石运回的费用为Di.请你帮它决策最小化费用. Input 第一行2个整数n,K.

【BZOJ4548】小奇的糖果 set(链表)+树状数组

[BZOJ4548]小奇的糖果 Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的颜色. Input 包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数. 接下来 T 组测试数据,对于每组测试数据,第一行输入两个正整数 N.K,分别表示点数和颜色数. 接下来 N 行,每行描述一个点,前两个数 x, y (|x|, |y| ≤ 2^30 - 1) 描述点的位置,最后一个数

【BZOJ4443】[Scoi2015]小凸玩矩阵 二分+二分图最大匹配

[BZOJ4443][Scoi2015]小凸玩矩阵 Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少. Input 第一行给出三个整数N,M,K 接下来N行,每行M个数字,用来描述这个矩阵 Output 如题 Sample Input 3 4 2 1 5 6 6 8 3 4 3 6 8 6 3 Sample Output 3 HINT 1<

4443: [Scoi2015]小凸玩矩阵

4443: [Scoi2015]小凸玩矩阵 Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少. Input 第一行给出三个整数N,M,K 接下来N行,每行M个数字,用来描述这个矩阵 Output 如题 Sample Input 3 4 2 1 5 6 6 8 3 4 3 6 8 6 3 Sample Output 3 HINT 1<=K&l