Codevs_1017_乘积最大_(划分型动态规划/记忆化搜索)
描述
http://codevs.cn/problem/1017/
给出一个n位数,在数字中间添加k个乘号,使得最终的乘积最大.
1017 乘积最大
2000年NOIP全国联赛普及组NOIP全国联赛提高组
今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:
设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。
同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:
有一个数字串:312, 当N=3,K=1时会有以下两种分法:
1) 3*12=36
2) 31*2=62
这时,符合题目要求的结果是:31*2=62
现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。
程序的输入共有两行:
第一行共有2个自然数N,K(6≤N≤40,1≤K≤6)
第二行是一个长度为N的数字串。
结果显示在屏幕上,相对于输入,应输出所求得的最大乘积(一个自然数)。
4 2
1231
62
本题由于比较老,数据实际也比较小,用long long 即可通过
分析
问题的关键就在于能不能看出来怎么划分.问题可以看作是在前n个数中使用k个乘号求最优解.那么前n个数中使用k个乘号是通过在前j(j<n)个数中使用k-1个乘号,其结果再乘上[j+1,n]表示的数字.如果用dp[i][k]表示在前i个数字中使用k个乘号所得到的最优解,那么dp[i][k]=max{dp[j][k-1]*[j+1,i]}(j<i).这里需要预处理出来A数组,其中A[i][j]表示[i,j]所表示的数字.
注意:
1.dp[i][k]从dp[j][k-1]来,所以要利用k-1的状态,所以k的循环应该在外层.
2.使用k个乘号,至少是前k+1个数字.
动态规划
#include <bits/stdc++.h>
using namespace std; typedef long long ll;
const int maxn=,maxk=;
int n,K;
char str[maxn];
ll A[maxn][maxn],dp[maxn][maxk]; void solve(){
for(int i=;i<=n;i++) dp[i][]=A[][i];
for(int k=;k<=K;k++)
for(int i=k+;i<=n;i++)
for(int j=k;j<i;j++)
dp[i][k]=max(dp[i][k],dp[j][k-]*A[j+][i]);
printf("%lld\n",dp[n][K]);
}
void init(){
scanf("%d%d%s",&n,&K,str+);
for(int i=;i<=n;i++){
A[i][i]=str[i]-'';
for(int j=i+;j<=n;j++)
A[i][j]=A[i][j-]*+(str[j]-'');
}
}
int main(){
init();
solve();
return ;
}
记忆化搜索
#include <bits/stdc++.h>
using namespace std; typedef long long ll;
const int maxn=,maxk=;
int n,K;
char str[maxn];
ll A[maxn][maxn],dp[maxn][maxk]; ll dfs(int m,int k){
if(dp[m][k]) return dp[m][k];
if(k==) return dp[m][k]=A[][m];
for(int i=k;i<m;i++)
dp[m][k]=max(dp[m][k],dfs(i,k-)*A[i+][m]);
return dp[m][k];
}
void init(){
scanf("%d%d%s",&n,&K,str+);
for(int i=;i<=n;i++){
A[i][i]=str[i]-'';
for(int j=i+;j<=n;j++)
A[i][j]=A[i][j-]*+(str[j]-'');
}
}
int main(){
init();
printf("%lld\n",dfs(n,K));
return ;
}
最新文章
- iOS 系统数字键盘左下角加确定按钮
- Django~Excel,PDF
- 【转】Hive配置文件中配置项的含义详解(收藏版)
- 桥接模式(Bridge)
- C语言位取反问题
- asr,tts,vsr
- jQuery formValidator手册
- freemarker中使用shiro标签
- 广州大学华软软件学院——NA视频下载
- SVN版本控制与Visual Studio 2012的完美结合
- predis如何实现phpredis的pconnect方法
- 读取和导出下载 excel 2003,2007 资料
- 【C#】Creating/Querying/Modifying the .mdb databases
- perl&#39;s Favorite Default: $_
- layui中进行form表单一些问题
- 嵌入式LINUX环境下视频采集知识
- 字符型转换为字符串ToString
- C#实现CRC校验
- kolla之docker私有仓库创建
- oracle 之 插入超长字段并包含&;字符的处理方法
热门文章
- WebView支持特效,页面内跳转(转载!)
- MVC小系列(三)【MVC的分部视图】
- C++ socket开发1
- CSS边框属性二---border-images
- 数学符号π (Pi)、Σ(Capital Sigma)、μ (Mu) 、σ(sigma)、∏(capital pi), ∫(Integral Symbol)的来历
- SGU 239.Minesweeper
- (转)Libevent(4)— Bufferevent
- MySQL配置文件详解
- thinkphp 整合 ucenter
- Cassandra CqlRow fetch DateType / Int32Type