【wikioi】1017 乘积最大
来源:互联网 发布:知所不知 编辑:程序博客网 时间:2024/04/27 18:35
题目链接
算法:划分型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 乘积最大
- 【wikioi】1017 乘积最大
- Wikioi 1017 乘积最大
- wikioi 1017 乘积最大
- wikioi 1017 乘积最大 普及组 2000
- wikioi p1017 乘积最大
- wikioi最大乘积
- wikioi-天梯-普及一等-划分dp-1017:乘积最大
- wikioi 1017 乘积最大 (2000年NOIP全国联赛普及组NOIP全国联赛提高组)
- wikioi 1017 乘积最大 (2000年NOIP全国联赛普及组NOIP全国联赛提高组)
- CODEVS 1017 乘积最大
- CodeVs 1017 乘积最大
- 1017 乘积最大
- 1017_乘积最大
- codevs 1017 乘积最大
- CODEVS 1017乘积最大
- CODEVS 1017 乘积最大
- 1017 乘积最大
- 【C语言版数据结构】线性表的链式表示,并且实现合并两个非递减有序排列到新的线性表
- 珠海公共自行车系统分析系列 - 硬件分析
- 单调队列-poj2823
- MFC 动态创建按钮及响应按钮消息
- Cocos2d-x CCNode 类的属性及与节点有关的函数
- 【wikioi】1017 乘积最大
- Java之数据库连接(一)
- java的技术要求!
- CONTENT-TYPE类型一览表
- C++ opencv小试4
- 快速排序
- 让IE浏览器支持HTML5标准的方法
- android 悬浮窗学习笔记
- http Keep-Alive 学习