洛谷 P1018 [NOIP2000 提高组] 乘积最大(dp,高精度)

传送门


解题思路

不得不说,这题恶心到我了,调了一个多小时。

第一次高精度把运算等写在struct里面,感觉良好。但是一定要注意初始化。

再就是高精乘高精最后的位数是两个位数相加,而不是相乘。

AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,k;
char s[55];
struct node{
	int a[50],num;
	node operator *(const node b)const{
		node res;
		res.num=num+b.num;
		for(int i=1;i<=45;i++) res.a[i]=0;
		for(int i=1;i<=num;i++){
			for(int j=1;j<=b.num;j++){
				res.a[i+j-1]+=a[i]*b.a[j];
			}
		}
		for(int i=1;i<=res.num;i++){
			res.a[i+1]+=res.a[i]/10;
			res.a[i]%=10;
		}
		while(res.num>1&&res.a[res.num]==0) res.num--;
		return res;
	}
	bool operator <(const node b)const{
		if(num!=b.num) return num<b.num;
		for(int i=num;i>=1;i--){
			if(a[i]!=b.a[i]) return a[i]<b.a[i];
		}
		return 1;
	}
}dp[50][10];
void print(node x){
	for(int i=x.num;i>=1;i--) cout<<x.a[i];
	cout<<endl;
}
node getnum(int l,int r){
	node res;
	res.num=r-l+1;
	for(int i=l;i<=r;i++){
		res.a[r-i+1]=s[i]-'0';
	}
	while(res.num>1&&res.a[res.num]==0) res.num--;
	return res;
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>s[i];
	for(int i=1;i<=n;i++){
		dp[i][0]=getnum(1,i);
	}
	for(int j=1;j<=k;j++){
		for(int i=1;i<=n;i++){
			if(j>=i) continue;
			for(int kkk=1;kkk<i;kkk++){
				if(j>kkk) continue;
				dp[i][j]=max(dp[i][j],dp[kkk][j-1]*getnum(kkk+1,i));
			}
		}
	}
	print(dp[n][k]);
	return 0;
}

//NOIP2000提高组 t2

posted @ 2021-09-24 18:34  尹昱钦  阅读(228)  评论(0编辑  收藏  举报