noip2000 乘积最大
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip2000 乘积最大相关的知识,希望对你有一定的参考价值。
问题转述:
给出一个长度N的数字串,要求使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。
分析:
动态规划解题。转移方程为:
f[i,k]=Maxf[j,k-1]*s[j+1,i] (j<i)
测试数据
6 1
101010 10100
8 4
321044105 5166000
8 3
22222222 234256
9 5
7777777777 1722499009
我的程序只能过一组 麻烦讲一下我的动规错到哪了 谢谢!
program t2(input,output);
var
ans:array[1..40,0..6]of int64;
str:string;
N,KK,i,j,k:integer;
num1,num2:int64;
procedure max(i,k:integer);
var
ii,num:integer;
temp:int64;
begin
for ii:= 1 to i-1 do
begin
val(copy(str,ii+1,i-ii),num);
temp:= ans[ii,k-1]*num;
if temp>ans[i,k] then ans[i,k]:=temp;
end;
end;
begin
fillchar(ans,sizeof(ans),0);
assign(input,'d:\t2.in');
reset(input);
readln(input,N,KK);
read(input,str);
close(input);
for i:= 1 to n do
begin
val(copy(str,1,i),num1);
ans[i,0]:=num1;
end;
for k:= 1 to KK do
for i:= k+1 to n do
max(i,k);
writeln(ans[i,k]);
end.
PROGRAM Maximum(input,output);
CONST maxn=40;
maxm=250;
VAR n,k,i,j,r:byte;
s:STRING[maxn];
tmp,ans:STRING[maxm];
f:ARRAY[1..maxn,boolean] OF STRING[maxm];
a,b,c:ARRAY[1..maxn] OF byte;
FUNCTION Mul(s1,s2:STRING[maxm]):STRING[maxm];
VAR l1,l2,l,i,j:byte;
BEGIN
fillchar(a,sizeof(a),0);
fillchar(b,sizeof(b),0);
fillchar(c,sizeof(c),0);
l1:=length(s1); l2:=length(s2);
FOR i:=1 TO l1 DO a[i]:=ord(s1[l1+1-i])-48;
FOR i:=1 TO l2 DO b[i]:=ord(s2[l2+1-i])-48;
FOR j:=1 TO l2 DO
FOR i:=1 TO l1 DO BEGIN
inc(c[i+j-1],a[i]*b[j]);
IF c[i+j-1]>9 THEN BEGIN
inc(c[i+j],c[i+j-1] DIV 10);
c[i+j-1]:=c[i+j-1] MOD 10
END;
END;
l:=l1+l2; WHILE (l>0) AND (c[l]=0) DO dec(l);
IF l=0 THEN l:=1;
Mul:='';
FOR i:=l DOWNTO 1 DO
Mul:=Mul+chr(c[i]+48)
END;
FUNCTION Greater(s1,s2:STRING[maxm]):boolean;
VAR l1,l2,k:byte;
BEGIN
l1:=length(s1); l2:=length(s2);
IF l1>l2 THEN EXIT(TRUE);
IF l1<l2 THEN EXIT(FALSE);
k:=1;
WHILE s1[k]=s2[k] DO inc(k);
IF s1[k]>s2[k] THEN EXIT(TRUE) ELSE EXIT(FALSE)
END;
BEGIN
assign(input,'d:\t2.in'); reset(input);
assign(output,'d:\t2.out'); rewrite(output);
readln(n,k);
readln(s);
FOR i:=2 TO n DO BEGIN
f[i,TRUE]:='0';
FOR j:=1 TO i-1 DO BEGIN
tmp:=Mul(copy(s,1,j),copy(s,j+1,i-j));
IF Greater(tmp,f[i,TRUE]) THEN f[i,TRUE]:=tmp
END;
END;
FOR r:=2 TO k DO
FOR i:=r+1 TO n DO BEGIN
f[i,odd(r)]:='0';
FOR j:=r TO i-1 DO BEGIN
tmp:=Mul(f[j,NOT odd(r)],copy(s,j+1,i-j));
IF Greater(tmp,f[i,odd(r)]) THEN f[i,odd(r)]:=tmp
END
END;
writeln(f[n,odd(k)]);
close(input); close(output)
END. 参考技术A 可以上我的博客看看
http://blog.sina.com.cn/s/blog_63d0cab00100lc0j.html
[NOIP2000] 提高组 洛谷P1018 乘积最大
题目描述
今年是国际数学联盟确定的“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
说明
NOIp2000提高组第二题
动态规划。
设f[乘号][前j个数]=最大乘积。每次枚举添加乘号的区间,求最大值即可。
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int mxn=60; 9 char s[300]; 10 int num[mxn][mxn]; 11 int gt(int i,int j){ 12 if(num[i][j])return num[i][j]; 13 int x=0; 14 for(int k=i;k<=j;k++){ 15 x=x*10+s[k]-‘0‘; 16 } 17 return num[i][j]=x; 18 } 19 int f[mxn][mxn]; 20 int n,K; 21 int main(){ 22 scanf("%d%d",&n,&K); 23 scanf("%s",s+1); 24 int i,j; 25 for(i=1;i<=n;i++)f[0][i]=gt(1,i); 26 for(int k=1;k<=K;k++){ 27 for(i=1;i<=n;i++){ 28 for(j=i;j>=k;--j){ 29 f[k][i]=max(f[k][i],f[k-1][j-1]*gt(j,i)); 30 } 31 } 32 } 33 printf("%d\n",f[K][n]); 34 return 0; 35 }
以上是关于noip2000 乘积最大的主要内容,如果未能解决你的问题,请参考以下文章