整数划分——区间dp(石子合并)
这不是将一个数以一来划分,而是把一个整数以位来划分
题目描述
如何把一个正整数N(N长度<20)划分为M(M>1)个部分,使这M个部分的乘积最大。N、M从键盘输入,输出最大值及一种划分方式。
输入格式
第一行一个正整数T(T<=10000),表示有T组数据。
接下来T行每行两个正整数N,M。
输出格式
对于每组数据
第一行输出最大值。
第二行输出划分方案,将N按顺序分成M个数输出,两个数之间用空格格开。
样例
样例输入
1
199 2
样例输出
171
19 9
这是递归思想,动态规划是正向的,而判断后是逆向的,输出时运用回溯,达到正向输出的目的
以下是代码
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- unsigned long long t,n[21],n2,n3[21][21],x,son[1000][1000],f[21][21],m;//数据极大,用无符号长整型
- string n1;
- int printf1(int a,int b)//输出函数,回溯
- {
- if(b==0)return 0;
- printf1(son[a][b],b-1);
- for(int i=son[a][b]+1;i<=a;i++)
- cout<<n[i];
- cout<<" ";
- }
- int main()
- {
- cin>>t;
- for(int l=1;l<=t;l++)
- {
- memset(n,0,sizeof(n));
- memset(son,0,sizeof(son));
- cin>>n1>>m;
- n2=n1.length();
- for(int i=0;i<=n2;i++)
- for(int j=0;j<=n2;j++)
- {
- f[i][j]=0;
- //n3[i][j]=1;
- }
- f[0][0]=1;
- for(int i=1;i<=n2;i++)
- {
- n[i]=n1[i-1]-'0';
- //cout<<n[i];
- }
- for(int i=1;i<=n2;i++)
- {
- x=n[i];
- for(int j=i;j<=n2;j++)
- {
- n3[i][j]=x;
- x*=10;
- x+=n[j+1];
- //cout<<n3[i][j]<<" "<<i<<" "<<j<<endl;
- }
- }
- for(int i=1;i<=n2;i++)
- {
- for(int j=1;j<=m&&j<=i;j++)
- {
- for(int k=1;k<=i;k++)
- {
- if(f[i][j]<f[k-1][j-1]*n3[k][i])
- {
- f[i][j]=f[k-1][j-1]*n3[k][i];
- //cout<<f[i][j];
- son[i][j]=k-1;//记录分割点
- }
- }
- }
- }
- cout<<f[n2][m]<<endl;
- if(m==n2)//特判,防止输出紊乱
- for(int i=1;i<=n2;i++)
- cout<<n[i]<<" ";
- else printf1(n2,m);
- cout<<endl;
- }
- }
石子合并
题目描述
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆最大得分.
输入格式
数据的第1行试正整数N,1≤N≤2000,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.
输出格式
输出共1行,最大得分
样例
样例输入
4
4 4 5 9
样例输出
54
最终一堆一定是前一次合并后,剩下的两堆相加的最优解。
状态转移方程
设t[i,j]表示从第i堆到第j堆石子数总和。
Fmax(i,j)表示将从第i堆石子合并到第j堆石子的最大的得分
Fmin(i,j)表示将从第i堆石子合并到第j堆石子的最小的得分(看题意要求没)
附上代码
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- int n,m[4001],m1[4001][4001],f[4001][4001],x,ma;
- int main()
- {
- cin>>n;
- for(int i=1;i<=n;i++)
- {
- cin>>m[i];
- }
- for(int i=1;i<=n;i++)
- {
- m[i+n]=m[i];
- }
- for(int i=1;i<=2*n-1;i++)
- {
- x=m[i];
- for(int j=i+1;j<=2*n-1;j++)
- {
- x+=m[j];
- m1[i][j]=x;
- }
- }
- for(int i=2*n-1;i>=1;i--)
- {
- for(int j=i;j<=2*n-1;j++)
- {
- f[i][j]=max(f[i+1][j],f[i][j-1])+m1[i][j];
- }
- }
- for(int i=1;i<=n;i++)
- {
- if(ma<f[i][i+n-1])ma=f[i][i+n-1];
- }
- cout<<ma;
- }
整数划分——区间dp(石子合并)的更多相关文章
- HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结
题意:给定一个字符串 输出回文子序列的个数 一个字符也算一个回文 很明显的区间dp 就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...
- 区间DP石子合并问题 & 四边形不等式优化
入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...
- SDUT3146:Integer division 2(整数划分区间dp)
题目:传送门 题目描述 This is a very simple problem, just like previous one. You are given a postive integer n ...
- DP石子合并问题
转自:http://www.hnyzsz.net/Article/ShowArticle.asp?ArticleID=735 [石子合并] 在一个圆形操场的四周摆放着n 堆石子.现要将石子有次序 ...
- 四边形不等式优化DP——石子合并问题 学习笔记
好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的 ...
- 51nod 1201 整数划分 基础DP
1201 整数划分 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} ...
- 51Nod 1201 整数划分 (经典dp)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 题意不多说了. dp[i][j]表示i这个数划分成j个数 ...
- HDU1294 Rooted Trees Problem(整数划分 组合数学 DP)
讲解见http://www.cnblogs.com/IMGavin/p/5621370.html, 4 可重组合 dfs枚举子树的节点个数,相乘再累加 1 #include<iostream& ...
- 「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G
[USACO16OPEN]248 G 题目: 题目描述 Bessie likes downloading games to play on her cell phone, even though sh ...
随机推荐
- 【参数校验】 自定义校验器 (实现ConstraintValidator)
日常工作中写接口时,往往需要校验前端传来的枚举状态码,例如"1","2"等等, 这里使用java 303规范的参数校验框架封装一个自定义参数校验器: /** * ...
- Backdoor.Zegost木马病毒分析(一)
http://blog.csdn.net/qq1084283172/article/details/50413426 一.样本信息 样本名称:rt55.exe 样本大小: 159288 字节 文件类型 ...
- 使用QT creator实现一个五子棋AI包括GUI实现(8K字超详细)
五子棋AI实现 五子棋游戏介绍 五子棋的定义 五子棋是全国智力运动会竞技项目之一,是具有完整信息的.确定性的.轮流行动的.两个游戏者的零和游戏.因此,五子棋是一个博弈问题. 五子棋的玩法 五子棋有两种 ...
- 文件描述符fd
java 后台运行程序命令 nohup java -jar babyshark-0.0.1-SNAPSHOT.jar > log.file 2>&1 & 命令解释:后台启动 ...
- 一个或多个listeners启动失败,更多详细信息查看对应的容器日志文件
碰到这个问题很多次,每次碰到都是去百度找.但是,不尽人意,好在最后还是解决了,所以写下总结. 报错内容: org.apache.catalina.core.StandardContext.startI ...
- layui处理表单/按钮进行多次提交
在一个项目中,我们最频繁的操作是CRUD,所以一定有涉及到按钮的操作.比如:确认保存,确认编辑,确认删除等等.所以,为了避免表单进行多次提交就显得特别地重要. 代码实现 知识点 $(':button' ...
- java之泛型的使用
在java中,普通的类和方法只能用具体的类型,这对代码的限制很大,代码的可重用性大大降低. 那么如何才能让同一个类和方法使用不同类型的对象呢?在接触泛型之前我们可能会想到通过类型转换的方法来实现. p ...
- MySQL备份脚本,应该这么写
前言: 数据库备份的重要性不言而喻,特别是在生产环境,任何数据的丢失都可能产生严重的后果.所以,无论什么环境,我们都应该有相应的备份策略来定时备份数据库.在 MySQL 中,比较常用的逻辑备份工具是 ...
- [BUAA2021软工助教]个人阅读作业#2小结
作业链接 见个人阅读作业#2 优秀作业推荐 Shaun_Yao ✍️ 道法之间--软工第2次博客作业 Potassium ✍️ 构之有道,建之有法--软工个人阅读作业#2 MarkDay ✍️ < ...
- Scrum Meeting 0
Basic Info where:五号教学楼 when:2020/4/21 target: 明确每次会议基本流程 简要汇报一下已完成任务,下一步计划与遇到的问题 Progress Team Membe ...