作者:灬哭着说再见灬 | 来源:互联网 | 2023-10-13 12:52
1166矩阵取数游戏2007年NOIP全国联赛提高组时间限制:1s空间限制:128000KB题目等级:黄金Gold题解题目描述Description【问题描述】帅帅经常跟同学玩一个
1166 矩阵取数游戏 2007年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 【问题描述】 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数。游戏规则如下: 1. 每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有元素; 2. 每次取走的各个元素只能是该元素所在行的行首或行尾; 3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素值*2i, 其中i 表示第i 次取数(从1 开始编号); 4. 游戏结束总得分为m次取数得分之和。 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。
输入描述 Input Description 第1行为两个用空格隔开的整数n和m。 第2~n+1 行为n*m矩阵,其中每行有m个用单个空格隔开的非负整数。
输出描述 Output Description 输出 仅包含1 行,为一个整数,即输入矩阵取数后的最大得分。
样例输入 Sample Input 2 3 1 2 3 3 4 2
样例输出 Sample Output 82
数据范围及提示 Data Size & Hint 样例解释
第 1 次:第1 行取行首元素,第2 行取行尾元素,本次得分为1*21+2*21=6 第2 次:两行均取行首元素,本次得分为2*22+3*22=20 第3 次:得分为3*23+4*23=56。总得分为6+20+56=82
【限制】 60%的数据满足&#xff1a;1<&#61;n, m<&#61;30, 答案不超过1016 100%的数据满足&#xff1a;1<&#61;n, m<&#61;80, 0<&#61;aij<&#61;1000
写在前面&#xff1a;我脱黄金坑了&#xff01;我脱黄金坑了&#xff01;我脱黄金坑了&#xff01;我脱黄金坑了&#xff01;我脱黄金坑了&#xff01;我脱黄金坑了&#xff01; —————————钻石の分界线———————— 解题思路&#xff1a;正确的做法是DP&#43;高精&#xff0c;但是我们都知道高精这个东西是非常恶心的存在&#xff0c;所以我们可以试着把它分成两个部分存储&#xff08;因为数据比较小&#xff0c;两个longlong足够&#xff09;&#xff0c;至于砖姨方程网上基本一致&#xff0c;我的也差不多&#xff08;实际上是自己想到一半不想想了然后就。。。&#xff09; 代码&#xff1a;
#include #include using namespace std ;long long maxnn(long long x,long long y,long long c,long long d) {if (c>d) return x;if (d>c) return y;if (x>y) return x;else return y; }long long a[100 ][100 ],n,m;long long f[101 ][101 ][101 ][2 ]; main() {long long p&#61;1 ;for (int i&#61;1 ;i<&#61;15 ;i&#43;&#43;) p*&#61;10 ;scanf ("%d%d" ,&n,&m);for (int i&#61;1 ;i<&#61;n;i&#43;&#43;)for (int j&#61;1 ;j<&#61;m;j&#43;&#43;)scanf ("%d" ,&a[i][j]);for (int i&#61;1 ;i<&#61;n;i&#43;&#43;)for (int j&#61;m;j>&#61;1 ;j--)for (int k&#61;j;k<&#61;m;k&#43;&#43;){f[i][j][k][1 ]*&#61;2 ;f[i][j][k][0 ]&#61;2 *maxnn(f[i][j&#43;1 ][k][0 ]&#43;a[i][j],f[i][j][k-1 ][0 ]&#43;a[i][k],f[i][j&#43;1 ][k][1 ],f[i][j][k-1 ][1 ]);f[i][j][k][1 ]&#43;&#61;2 *max(f[i][j&#43;1 ][k][1 ],f[i][j][k-1 ][1 ]);long long tt&#61;f[i][j][k][0 ]/p;if (tt!&#61;0 ) {f[i][j][k][1 ]&#43;&#61;tt;f[i][j][k][0 ]%&#61;p;}}long long ans&#61;0 ;for (int i&#61;1 ;i<&#61;n;i&#43;&#43;){f[0 ][1 ][m][1 ]&#43;&#61;f[i][1 ][m][1 ];f[0 ][1 ][m][0 ]&#43;&#61;f[i][1 ][m][0 ];long long tt&#61;f[0 ][1 ][m][0 ]/p;if (tt!&#61;0 ) {f[0 ][1 ][m][1 ]&#43;&#61;tt;f[0 ][1 ][m][0 ]%&#61;p;}}if (f[0 ][1 ][m][1 ]!&#61;0 )printf ("%lld %lld" ,f[0 ][1 ][m][1 ],f[0 ][1 ][m][0 ]);else printf ("%lld" ,f[0 ][1 ][m][0 ]); }