991 AlvinZH的奇幻猜想----整数乘积plus(背包DP大作战P)
914 AlvinZH的奇幻猜想----整数乘积puls
思路
难题。动态规划。
将数字串按字符串输入,处理起来更方便些。
dp[i][j]:表示str[0~i]中插入j个乘号时的乘积最大值。状态转移方程为:dp[i][j] = max(dp[i][j], dp[i-k][j-1]*convert(i-k+1,i)),k∈[1,i-j+1],convert为数字转换函数。
注意:本题在上一题的基础上,数字串变得很长,long long根本处理不了。
方法:大数乘法。定义大数结构体,用数组存下每一位数字,做乘法时一位一位处理。建议百度学习一下大数的加减乘除,这是常见的一个面试题。具体见参考代码一。
当然,你要是会java的话,直接用BigInteger也行,简单,时间会大了点,不影响过题。具体见参考代码二。
参考代码一
//
// Created by AlvinZH on 2017/10/31.
// Copyright (c) AlvinZH. All rights reserved.
//
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct BigNum {
int len;
int num[100];
};
int n, kk;
char s[105];//数字串
int A[105];//原数字
BigNum dp[105][12];//dp[i][j]表示前i个数字有j个乘号时的最大值。
BigNum cal(BigNum x, int l, int r)
{
BigNum ans, y;
memset(ans.num, 0, sizeof(ans.num));
memset(y.num, 0, sizeof(y.num));
y.len = r - l + 1;
for (int i = r; i >= l; --i)
y.num[r-i+1] = A[i];
for (int i = 1; i <= x.len; ++i) {
for (int j = 1; j <= y.len; ++j) {
ans.num[i+j-1] += x.num[i] * y.num[j];
}
}
int newLen = x.len + y.len -1;
for (int i = 1; i <= newLen; ++i) {
ans.num[i+1] += ans.num[i]/10;
ans.num[i] = ans.num[i]%10;
}
if(ans.num[newLen+1] > 0) newLen++;
ans.len = newLen;
/*for (int i = ans.len; i >= 1; --i)
printf("%d", ans.num[i]);
printf("\n");*/
return ans;
}
BigNum cmp(BigNum x, BigNum y)//比较大小
{
if(x.len > y.len) return x;
else if(x.len < y.len) return y;
for (int i = x.len; i >=1 ; --i) {
if(x.num[i] > y.num[i]) return x;
else if(x.num[i] < y.num[i]) return y;
}
return x;
}
int main()
{
//freopen("in1.txt", "r", stdin);
//freopen("outme.txt", "w", stdout);
while(~scanf("%d %s", &kk, s))
{
for (int i = 0; i < 105; ++i) {
for (int j = 0; j < 12; ++j) {
dp[i][j].len = 0;
memset(dp[i][j].num, 0, sizeof(dp[i][j]));
}
}
n = strlen(s);
for (int i = 1; i <= n; ++i)
A[i] = s[i-1] - '0';
//初始化没有添加乘号的情况
for (int i = 1; i <= n; ++i) {
for (int j = i; j >= 1; --j) {
dp[i][0].num[++dp[i][0].len] = A[j];
}
}
for (int i = 2; i <= n; ++i) {
for (int k = 1; k <= min(kk, i-1); ++k) {
for (int j = k; j < i; ++j) {
dp[i][k] = cmp(dp[i][k], cal(dp[j][k-1], j+1, i));
}
}
}
for (int i = dp[n][kk].len; i >= 1; --i) {
printf("%d", dp[n][kk].num[i]);
if(dp[n][kk].num[dp[n][kk].len] == 0) break;
}
printf("\n");
}
}
参考代码二
/*
Author: 赵立晨(12657)
Result: AC Submission_id: 402925
Created at: Sun Nov 12 2017 13:24:46 GMT+0800 (CST)
Problem: 914 Time: 451 Memory: 48880
*/
//package main;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String args[]){
BigInteger dp[][]=new BigInteger[107][17];
BigInteger num[][]=new BigInteger[107][107];
Scanner in=new Scanner(System.in);
while (in.hasNext()){
for (int i=0;i<=100;i++)
for (int j=0;j<=10;j++) dp[i][j]=BigInteger.ZERO;
int n=in.nextInt();
String a=in.next();
for (int i=0;i<a.length();i++){
for (int j=i;j<a.length();j++){
num[i][j]=new BigInteger(a.substring(i,j+1));
}
}
dp[0][0]=BigInteger.ZERO;
for (int i=0;i<a.length();i++) dp[i][0]=num[0][i];
for (int i=0;i<a.length();i++){
for (int k=1;k<=n;k++){
for (int j=1;j<=i;j++){
dp[i][k]=dp[i][k].max(dp[j-1][k-1].multiply(num[j][i]));
}
}
}
System.out.println(dp[a.length()-1][n]);
}
in.close();
}
}
991 AlvinZH的奇幻猜想----整数乘积plus(背包DP大作战P)的更多相关文章
- 906 AlvinZH的奇幻猜想----整数乘积(背包DP大作战O)
906 AlvinZH的奇幻猜想----整数乘积 思路 难题.动态规划. 将数字串按字符串输入,处理起来更方便些. dp[i][j]:表示str[0~i]中插入j个乘号时的乘积最大值.状态转移方程为: ...
- AlvinZH掉坑系列讲解(背包DP大作战H~M)
本文由AlvinZH所写,欢迎学习引用,如有错误或更优化方法,欢迎讨论,联系方式QQ:1329284394. 前言 动态规划(Dynamic Programming),是一个神奇的东西.DP只能意会, ...
- 977 AlvinZH过生日(背包DP大作战S)
977 AlvinZH过生日 思路 难题.逆推DP. 要明确dp的状态只与是否有选择权有关,而与选择权在谁手里无关.因为不论选择权在谁手里,那个人都会尽可能的获得最大的蛋糕重量. dp[i]表示分配到 ...
- 976 AlvinZH想回家(背包DP大作战T)
976 AlvinZH想回家 思路 如果在第i小时有一些飞机延误,那么一架飞机的c值越大,这一小时产生的损失也越大.而使这一小时产生的损失尽可能的小并不会导致接下来时间产生的损失增大.因此应当每一小时 ...
- 963 AlvinZH打怪刷经验(背包DP大作战R)
963 AlvinZH打怪刷经验 思路 这不是一道普通的01背包题.大家仔细观察数据的范围,可以发现如果按常理来的话,背包容量特别大,你也会TLE. 方法一:考虑01背包的一个常数优化----作用甚微 ...
- 851 AlvinZH的鬼畜密码(背包DP大作战N)
851 AlvinZH的鬼畜密码 思路 难题.动态规划. 先判断字符串是否合理(可翻译),然后分段处理,每一小段用动态规划求出解法数. dp[i]:字符串str[0~i]的解法数.通过判断str[i] ...
- 2016级算法第三次上机-C.AlvinZH的奇幻猜想——三次方
905 AlvinZH的奇幻猜想--三次方 思路 中等题.题意简单,题目说得简单,把一个数分成多个立方数的和,问最小立方数个数. 脑子转得快的马上想到贪心,从最近的三次方数往下减,反正有1^3在最后撑 ...
- 算法-找出与目标数字相同的digit组成的整数中比该数字大的数集中的最小数字
题目: 给出1个正整数,找到用与这个数字相同的digit组成的整数中比这个数字大的数集中的最小数字.比如:12352874 的结果是 12354278 分析: 这道题目的考虑目标是数组的查找与排序. ...
- Ural 1158. Censored! 有限状态自动机+DP+大整数
Ural1158 看上去很困难的一道题. 原文地址 http://blog.csdn.net/prolightsfxjh/article/details/54729646 题意:给出n个不同的字符,用 ...
随机推荐
- 使用Qt Installer Framework制作软件安装包
概述 Qt Installer Framework(缩写QIF)是Qt官方用于生成软件安装包的工具.包括Qt Creator和Qt Installer Framework自身的安装包都是由这个工具制作 ...
- jQuery中deferred对象的使用(二)
接上一回的内容,漏了一个always()方法,参数也是回调函数,与done和fail不同的是,无论任何情况都执行always方法中的回调. deferred对象的使用(二) deferred对象不光可 ...
- Ubuntu14.04下FTP服务器的搭建配置 标签: ubuntuftp服务器虚拟机 2017-06-13 15:24 161人阅读 评
首先说明一下,我是在虚拟机中装的Ubuntu14.04,物理机是Win10,最初只是为了在两个系统间传输文件才在Ubuntu中安装了ftp服务器,从Windows端登陆其即可.最初也是按照网上的各种教 ...
- a Concise Sparse Matrix package
简明稀疏矩阵包 https://github.com/kulhanek/csparse https://github.com/kulhanek/csparse
- .net 自定义AOP,透明代理与真实代理
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.R ...
- rocketmq配置项说明(对应版本:4.0.0-incubating)
Broker配置参数说明 自定义客户端行为 ※一些默认配置的源代码路径 org.apache.rocketmq.store.config --END--
- ORACLE 异机恢复
有时候需要将大的数据库发布到客户现场或转移机器时,不得不考虑在异机上恢复已经调整.测试好的库. dumpdp 全备的方法虽然易用,但在处理对象.索引.空间的时候异常的出错,比如:见有些公司,建表.索引 ...
- Python 2.6 安装wxPython后提示"64.....32"错误解决办法
ImportError: /usr/local/lib/wxPython-unicode-2.8.10.1/lib/python2.6/site-packages/wx-2.8-mac-unicode ...
- IO编程之writelines方法
1.使用with open as 函数写入文件 2.创建后的文件名为database.txt 3.创建一个函数进行读取文件,使用for循环遍历整个文件内容 4.使用if __name__=='__ma ...
- TCP协议三次握手连接四次握手断开和DOS攻击
转载:http://blog.csdn.net/fw0124/article/details/7452695 TCP连接的状态图 TCP建立连接的三次握手过程,以及关闭连接的四次握手过程 贴一个tel ...