题目链接

算法:划分型DP

非常典型的一道题目,划分型DP

题目描述:

设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:有一个数字串:312, 当N=3,K=1时会有以下两种分法:

1)  3*12=36

2)  31*2=62

这时,符合题目要求的结果是:31*2=62现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。

设数字串为a1a2a3……an。当k=1时,最大值为

max{a1*a2a3……an,  a1a2*a3……an,  ……  ,  a1a2a3……an-1*an}

当k=2时,最大值为

max{a1*a2*a3……an,  a1*a2a3……*an,  ……  ,  a1a2a3……*an-1*an}

引入记号f[i,k]表示从a0到ai,插入k个乘号所取得的最大值,用c[i,j]表示从ai到aj的数字列,则:

K=1时

f[n,1]=max{c[1,1]*c[2,n],  c[1,2]*c[3,n],  ……  ,  c[1,n-1]*c[n,n]}

K=2时

f[n,2]=max{f[n-1,1]*c[n,n],  f[n-2,1]*c[n-1,n],  ……  ,  f[2,1]*c[3,n]}

所以导出

f[n,k]=max{f[n-1,k-1]*c[n,n],  f[n-2,k-1]*c[n-1,n],  .......  , f[k,k-1]*c[k+1,n]}

我们用F[n][k]来表示f[n,k],表示划分k次得到的数最大,用A[i][j]表示c[i,j]

得到:

F[i][1] = max(F[i][1], A[1][j]*A[j+1][i])  (1 <= j < i)

F[i][k] = max(F[i][k], A[j+1][i]*F[j][k-1]) (k <= j < i)

其实这里可以简化成:

F[i][0] = A[1][i]  (1 <= i <= n)

F[i][k] = max(F[i][k], A[j+1][i]*F[j][k-1]) (k <= j < i, 1 <= k <= m) m是要添加的乘号数目

而且发现,方程是以划分次数k为阶段,且顺序是递增(从k到i枚举j即可),那么我们就自底向上的来递推

所以顺序就一木了然了

上代码:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std; int n, m, i, j, k;
const int MAXK = 10;
const int MAXN = 100;
int c[MAXN] = {0}, A[MAXN][MAXN] = {{0,0}}, F[MAXN][MAXK] = {{0,0}};
int makeConut(int x, int y) //求x到y之间的数字列
{
int ans = 0;
while(x <= y) ans = ans * 10 + c[x++];
return ans;
} int main()
{
string str;
cin >> n >> m;
cin >> str;
for(i = 1; i <= n;i++) c[i] = (str[i-1]-'0');
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
A[i][j] = makeConut(i, j); //初始化A数组
//初始化k=0时的情况
//F[i][0] = A[1][i] (1 <= i <= n)
for(i = 1; i <= n; i++)
F[i][0] = A[1][i];
//DP
//F[i][k] = max(F[i][k], A[j+1][i]*F[j][k-1]) (1 <= k <= m)
for(k = 1; k <= m; k++)
for(i = k+1; i <= n; i++)
for(j = i-1; j >= k; j--)
F[i][k] = max(F[i][k], A[j+1][i]*F[j][k-1]);
cout << F[n][m] << endl;
return 0;
}

【wikioi】1017 乘积最大的更多相关文章

  1. wikioi 1017 乘积最大

    dp[i][j]=max(dp[i][j],dp[t][k-1]*mapn[t+1][i]); dp[i][j]代表从0-i之间有j个乘号,mapn[i][j]表示第i位到第j位的数究竟是多少 #in ...

  2. codevs 1017 乘积最大

    1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描 ...

  3. codevs 1017 乘积最大 dp

    1017 乘积最大 时间限制: 1 s 空间限制: 128000 KB         题目描述 Description 今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚 ...

  4. 1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组

    1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组   #include <iostream> #include <string> #include & ...

  5. codevs——1017 乘积最大

    1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Desc ...

  6. Codevs 1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组

    1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 今年是国 ...

  7. 【动态规划】【记忆化搜索】1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组

    跟CODEVS 3415没有什么区别,也不用高精度. http://www.cnblogs.com/autsky-jadek/p/4055184.html #include<cstdio> ...

  8. [NOIP复习]第三章:动态规划

    一.背包问题 最基础的一类动规问题.相似之处在于给n个物品或无穷多物品或不同种类的物品,每种物品仅仅有一个或若干个,给一个背包装入这些物品,要求在不超出背包容量的范围内,使得获得的价值或占用体积尽可能 ...

  9. 【wikioi】1040 统计单词个数

    题目链接 算法:划分型DP PS:被卡过3天.日期:2013-10-10 ~ 2013-10-12 18:52:48 这题是我提交了13次AC= =汗= = 题目描述: 给出一个长度不超过200的由小 ...

随机推荐

  1. gcc参数-l传递顺序错误导致`undefined reference'的一点小结

    刚才编译一个pthread的单文件程序, 使用的命令行是: gcc -o thread1 -lpthread thread1.c 结果报错: $ gcc -o thread1 -lpthread th ...

  2. android 运行时出现The connection to adb is down, and a severe error has occured.(转)

    点击项目run,报了这样的错,前几天都好好的:   [2013-09-14 15:27:13 - QualityPicture_Client1.3.1.9.7.1] ----------------- ...

  3. 【leetcode】Single Number && Single Number II(ORZ 位运算)

    题目描述: Single Number Given an array of integers, every element appears twice except for one. Find tha ...

  4. 深入分析JavaWeb 技术内幕

    1,通过浏览器请求一个资源,会发生以下几种过程 1) http的解析过程,包括对于http请求头和响应头中指令(控制用户浏览器的渲染行为和 服务器的执行逻辑)的解析 2)DNS的解析过程(根据域名获取 ...

  5. android:layout_weight属性详解 (转)

    在android开发中LinearLayout很常用,LinearLayout的内控件的android:layout_weight在某些场景显得非常重要,比如我们需要按比例显示.android并没用提 ...

  6. TCP状态转换图详解

    以下对几个关键的中间状态进行说明: 三次握手: LISTEN:表示服务器的某个SOCKET处于监听状态,可以进行连接了. SYN_SENT:表示客户端的某个SOCKET与服务器进行connect时,首 ...

  7. DIV伸缩盒子box

    <div class="div1"> <div class="box"> <div>A</div> <di ...

  8. loadrunner实现浮点型数据转换成字符串

    ftoa(float floatNum, char *convFloatString) { char new[10]; float number,dTemp,temp_val; int base, f ...

  9. PS切图的几种方式

    方法一 点击图层右键-->导出为 导出需要的格式与大小 方法二 选择多个图层右键--->快速导出为PNG(导出的名字就是图层名字) 方法三

  10. 手机页面的meta标签

    <meta charset="utf-8"/><meta name="viewport" content="width=device ...