RQNOJ 311 [NOIP2000]乘积最大:划分型dp
来源:互联网 发布:多功能qq视频录像软件 编辑:程序博客网 时间:2024/05/20 17:25
题目链接:https://www.rqnoj.cn/problem/311
题意:
给你一个长度为n的数字,用t个乘号分开,问你分开后乘积最大为多少。(6<=n<=40,1<=k<=30)
题解:
简化问题:
给原数字之前添加一个"1 *",乘号不计入数量,对答案无影响。
例如:"1231"可以变成"(1*)1231"。
表示状态:
dp[i][j] = max num(最后一个乘号之前的最大乘积)
i:此时在第i个数的前面添了一个乘号
j:用了j个乘号
例1:"(1*)12*31":
dp[2][1] = 12 (数位从0开始从左向右编号)
例2:"(1*)12*3*1"
dp[3][2] = 12*3 = 36
找出答案:
max dp[i][t] * cal_sec(i,n-1)
cal_sec(x,y)将数字串中[x,y]这个区间的字符串转化为数字
例如:设n=4,t=1.
此时为"(1*)12*31"
则此时这种方案的乘积为dp[2][1]* "31" = 12*31
如何转移:
dp[i][j] = max dp[k][j-1] * cal_sec(k,i-1)
在前面的某一段乘积后面再续上一串数字,达到第i位,用了j个乘号。
前面的某一段乘积:枚举最后一个乘号在第k个数字之前,用了j-1个乘号。
要续的数字:从第k位到i-1位 = cal_sec(k,i-1)
边界条件:
初始时用了0个乘号,但乘积为1。
例如:"(1*)1231".
特判:如果输入的数字就是0,则直接返回0.
注:输入用string,答案用long long存。
数据水。。。否则高精。。。
AC Code:
1 // state expression: 2 // dp[i][j] = max num 3 // i: last '*' is in front of ith bit 4 // j: used j '*' 5 // 6 // find the answer: 7 // max dp[i][t] * cal_sec(i,len-1) 8 // 9 // transferring:10 // dp[i][j] = max dp[k][j-1] * cal_sec(k,i-1)11 //12 // boundary:13 // if input == 0: return 014 // else dp[0] = 1, others = -115 #include <iostream>16 #include <stdio.h>17 #include <string.h>18 #define MAX_N 4519 #define MAX_K 3520 21 using namespace std;22 23 int n,t;24 long long ans;25 long long dp[MAX_N][MAX_K];26 long long sec[MAX_N][MAX_N];27 string s;28 29 void read()30 {31 cin>>n>>t>>s;32 }33 34 long long cal_sec(int x,int y)35 {36 if(sec[x][y]!=-1) return sec[x][y];37 long long res=0;38 for(int i=x;i<=y;i++)39 {40 res=res*10+s[i]-'0';41 }42 return sec[x][y]=res;43 }44 45 void solve()46 {47 memset(sec,-1,sizeof(sec));48 memset(dp,-1,sizeof(dp));49 dp[0][0]=1;50 for(int i=1;i<n;i++)51 {52 for(int j=1;j<=t && j<=i;j++)53 {54 for(int k=0;k<i;k++)55 {56 if(dp[k][j-1]!=-1)57 {58 dp[i][j]=max(dp[i][j],dp[k][j-1]*cal_sec(k,i-1));59 }60 }61 }62 }63 ans=0;64 for(int i=0;i<n;i++)65 {66 if(dp[i][t]!=-1) ans=max(ans,dp[i][t]*cal_sec(i,n-1));67 }68 }69 70 void print()71 {72 cout<<ans<<endl;73 }74 75 int main()76 {77 read();78 solve();79 print();80 }
- RQNOJ 311 [NOIP2000]乘积最大:划分型dp
- 【划分型DP】乘积最大
- RQNOJ 311 乘积最大
- ACM 87. [NOIP2000] 乘积最大(水dp)
- <划分型DP>【noip 2000】乘积最大
- [NOIP2000] 乘积最大
- 【NOIP2000】乘积最大
- NOIP2000乘积最大
- noip2000乘积最大c++
- NOIP2000 乘积最大
- 【NOIP2000】乘积最大
- 【NOIP2000提高】乘积最大
- NOIP 2000乘积最大 解题报告(划分型DP)
- Code[VS] 1017 乘积最大 (划分型DP)
- [NOIP2000] 乘积最大-解题报告
- 乘积最大codevs1017(noip2000)
- NOIP2000提高组 乘积最大
- 【动态规划】【RQNOJ】乘积最大
- PHP-单双引号的区别
- Unity入门学习 //02_Scene窗口
- linq语句—类型转换
- MySQL性能优化之参数配置
- Spring初探之AOP(面向切面编程)
- RQNOJ 311 [NOIP2000]乘积最大:划分型dp
- Office365学生订阅+Visio2016ProVOL
- jvm之对象的创建
- adb发送广播
- pyhs2读取Hive
- PLSQL创建命名空间和用户以及授权
- java excel导入和导出(poi,jxl)
- js把变量设置成缓存并给下一个页面的input赋值
- 1-2、数字图像处理基础