2018农大校赛(大数+dp)

萌新的数学

Description

YHR这人,对于数字非常着迷,达到了废寝忘食的地步,最近他看到了一个有意思的数学题目,

已经好久不和异性交流了,但是琢磨了太久了,还是没有把这个数学问题研究出来,为了早日

和异性聊上天,所以他求助于聪明的你,你能帮他把问题解决出来吗?

设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得

这K+1个部分的乘积能够为最大。

比如有一个数字串:312, 当N=3,K=1时会有以下两种分法:

1) 3*12=36
2) 31*2=62

这时,符合题目要求的结果是:31*2=62

现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。

扫描二维码关注公众号,回复: 1068148 查看本文章

Input

程序的输入共有两行:

第一行共有2个自然数N,K(6≤N≤40,1≤K≤6)

第二行是一个长度为N的数字串。

Output

结果显示在屏幕上,相对于输入,应输出所求得的最大乘积(一个自然数)。


其实题目不难,主要是我大数模板用了自己的,写了四个小时的大数,缝缝补补,一直修改大数的运算,终于过了,我再也不自己写大数模板了,令人窒息。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;

struct node{  
    int m[50];  
    int po;       //我的下标不应该从0开始 ,乘的时候出错了, 
	
}dp[50][50]; 

const int mx = 0;
int n,k,len,num[30];
char s1[45]; 

void dis(node a){  
    //cout<<"结果"<<endl;  
    for(int i = a.po; i>=0; i--)  
        cout<<a.m[i];  
    cout<<endl;  
}
node mul(node s1, node s2){  
    node te;                        //结构体没有初始化非常的危险,数组里面的数都是随机的,大部分为0
    if(s2.po == -1)
    	s2.m[0] = 1;
    memset(te.m, 0, sizeof(te.m));  
    //int ob;
    for(int i = 0; i <= s1.po; i++)  
        for(int j = 0; j <= s2.po; j++){  
           te.m[i + j] += s1.m[i] * s2.m[j];  
        }   
    te.po = s1.po + s2.po;  
    //ob = 0;
    for(int i = 0; i <= te.po; i++){  
       
		if(te.m[i] > 9){  
            te.m[i + 1] += te.m[i] / 10;  
            te.m[i] = te.m[i] % 10;   
        }  
    }  
    
    if(te.m[te.po+1] > 0)  
        te.po++;
		 
	return te;  
} 

node add(node a, int x){  
	a.m[0] += x;
	
  	for(int i = 0; i <= a.po; i++){  
       
		if(a.m[i] > 9){  
            a.m[i + 1] += a.m[i] / 10;  
            a.m[i] = a.m[i] % 10;   
        }  
    }  
    
    if(a.m[a.po+1] > 0)  
        a.po++;
        
    return a;  
      
}   

node ti(int st, int en){
	node te;
	int a = -1;
	memset(te.m,0,sizeof(te.m));
	for(int i = en; i >= st; i--){
		te.m[++a]= num[i];
	}
	te.po = a;
	/*cout<<"ti=";
	dis(te);*/
	return te;
}
bool cmp(node a, node b){
	if(a.po != b.po)
		return (a.po > b.po);
		
	for(int i = a.po; i >= 0; i--)
		if(a.m[i] > b.m[i]) 
			return true;
		else if(a.m[i] < b.m[i])
			return false;
			
	return false;
	
}	
int main(){
	scanf("%d%d",&n,&k);
	scanf("%s",s1);
	len  = strlen(s1);
	for(int i = 0; i < len; i ++)
		num[i] = s1[i] - '0';
	
	for(int i = 0; i < 50; i++)
		for(int j = 0; j < 50; j++){
			memset(dp[i][j].m,0,sizeof(dp[i][j].m));
			dp[i][j].po = -1;
		}
		
	dp[0][0].m[0]= num[0];
	dp[0][0].po = 0;
	
	node te,t2;
	te.m[0]= 0; te.m[1] = 1;   // te = 10
	te.po = 1;                   //忘记赋值为1 
	for(int i = 1; i < len; i++){
		dp[i][0] = mul(dp[i-1][0],te);
		dp[i][0] = add(dp[i][0],num[i]);
	 
	}
	memset(te.m,0,sizeof(te.m));
	
	for(int i = 1; i < len; i++)
		for(int j = 1; j <= i &&j <= k; j++)
			for(int k = i; k >0; k--){                          // // k >= j  忘了加进去 
				if( cmp( mul(ti(k,i),dp[k-1][j-1]) ,dp[i][j]))	 //写反了 
				//	dp[i][j] = max(dp[i][j],ti(k,i)*dp[k-1][j-1]);
					dp[i][j] = mul(ti(k,i),dp[k-1][j-1]);
					
				
			}
		
	dis(dp[len-1][k]);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37325947/article/details/80085922