这不是将一个数以一来划分,而是把一个整数以位来划分

题目描述

如何把一个正整数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(石子合并)的更多相关文章

  1. HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结

    题意:给定一个字符串 输出回文子序列的个数    一个字符也算一个回文 很明显的区间dp  就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...

  2. 区间DP石子合并问题 & 四边形不等式优化

    入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...

  3. SDUT3146:Integer division 2(整数划分区间dp)

    题目:传送门 题目描述 This is a very simple problem, just like previous one. You are given a postive integer n ...

  4. DP石子合并问题

    转自:http://www.hnyzsz.net/Article/ShowArticle.asp?ArticleID=735 [石子合并]    在一个圆形操场的四周摆放着n 堆石子.现要将石子有次序 ...

  5. 四边形不等式优化DP——石子合并问题 学习笔记

    好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的 ...

  6. 51nod 1201 整数划分 基础DP

    1201 整数划分  基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} ...

  7. 51Nod 1201 整数划分 (经典dp)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 题意不多说了. dp[i][j]表示i这个数划分成j个数 ...

  8. HDU1294 Rooted Trees Problem(整数划分 组合数学 DP)

    讲解见http://www.cnblogs.com/IMGavin/p/5621370.html, 4 可重组合 dfs枚举子树的节点个数,相乘再累加  1 #include<iostream& ...

  9. 「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G

    [USACO16OPEN]248 G 题目: 题目描述 Bessie likes downloading games to play on her cell phone, even though sh ...

随机推荐

  1. python 爬取王者荣耀英雄皮肤代码

    import os, time, requests, json, re, sys from retrying import retry from urllib import parse "& ...

  2. Linux启动流程和服务管理(init和systemd)

    目录 一:Linux启动流程 init和Systemd的区别 二:Linux服务管理(service,systemctl) 一:Linux启动流程 Rhel6启动过程: Rhel7启动过程: GRUB ...

  3. hdu3585 二分最大团(dp优化)

    题意       给你一些点( <= 50),让你找到k个点,使得他们之间的最小距离最大. 思路:       求最小的最大,我们可以直接二分去枚举距离,但是要注意,不要去二分double找距离 ...

  4. Intel汇编语言程序设计学习-第六章 条件处理-下

    6.6  应用:有限状态机 这个东西说了半天,感觉就是把逻辑弄得跟有向图一样,没看出来什么高端的东西,下面就整理下书上说的概念: 有限状态机(FSM,Finite-State Machine)是依据输 ...

  5. node-mongo封装

    node 里面调用mongo封装了下. mongo.js文件 const { MongoClient, ObjectId } = require('mongodb'); const mongourl ...

  6. 【Git】2. Git常用命令详解、版本切换原理

    一.新增文件 1.设置用户签名 签名的作用就是为了区分不同的人,方便查看版本的时候知道操作的人是谁.首次安装好git之后必须设置一下签名,否则无法提交代码. 另外,这里设置的签名跟你登录到远程仓的账号 ...

  7. Andrew Ng机器学习算法入门((五):矩阵和向量

    矩阵定义 数学上,一个m×n的矩阵是一个由m行n列元素排列成的矩形阵列 使用Aij来获取矩阵中第i行j列的数据 向量的定义 向量就是n行1列的特殊矩阵 由于向量仅仅只有1行,那么通过一个变量i来指定获 ...

  8. 【js】Leetcode每日一题-完成所有工作的最短时间

    [js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...

  9. Day001 Typora Markdown语法学习

    # Markdown语法 ## 标题 ### 三级标题 #### 四级标题 注:最多支持到六级标题 ## 字体 **hello,world!** *hello,world!* ***hello,wor ...

  10. Mac 解压缩软件-keka

    去官网 GitHub地址 功能预览