zoukankan      html  css  js  c++  java
  • 洛谷P1018 乘积最大两种做法

    目前整理了两种做法

    方法一:

    设a为输入的字符串,num【i】【j】表示字符串中从下标为i到j(故从0开始)的一串数字。那么可以得到

    for(int i=0;i<n;i++)  num[ i ][ i ]=a[ i ]-'0';
    for(int i=0;i<n;i++)
    for(int j=i+1;j<n;j++)
    num[i][j]=num[i][j-1]*10+a[j]-'0';

    这是一个递推,第一行是设置边界,递推关系式即num[i][j]=num[i][j-1]*10+a[j]-'0';

    设f【i】【j】表示在0到i间加入i个乘号的最大乘积,则状态转移方程为:

    for(int k=1;k<=x;k++)
    for(int i=k;i<n;i++)//注意i从0开始
    for(int j=k-1;j<i;j++)
    f[k][i]=max(f[k][i],f[k-1][j]*num[j+1][i]);

    边界设置如下:

    for(int i=0;i<n;i++)
    f[0][i]=num[0][i];代码如下,但这样只有60分,AC需要使用高精度乘法,下次再加上

    #include<cstdlib>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=41;
    char a[N];
    int x,n,len;
    long long f[N][N],num[N][N];
    int main()
    {
        //freopen("in.txt","r",stdin);
        cin>>n>>x;
        cin>>a;
        for(int i=0;i<n;i++) num[i][i]=a[i]-'0';
        for(int i=0;i<n;i++)
           for(int j=i+1;j<n;j++)
            num[i][j]=num[i][j-1]*10+a[j]-'0';
            
        for(int i=0;i<n;i++)
        f[0][i]=num[0][i];  
        for(int k=1;k<=x;k++)
          for(int i=k;i<n;i++)//注意i从0开始 
            for(int j=k-1;j<i;j++)
            f[k][i]=max(f[k][i],f[k-1][j]*num[j+1][i]);
        cout<<f[x][n-1];/**/
        
        return 0;
    }
    方法二:
    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,k,maxx;
    int a[41];
    char ch;
    void dfs(int x,int ans,int last)
    {
        if(x==k)
        {
        int mul=0;
        for(int j=last+1;j<n;j++)
        {mul+=a[j];
        mul*=10;}
        mul+=a[n];
        maxx=max(maxx,ans*mul);
        return;
        }
        for(int i=last+1;i<=n-k+x;i++)
        {
            int mul=0;
            for(int j=last+1;j<i;j++)
            {mul+=a[j];
            mul*=10;}
            mul+=a[i];
            dfs(x+1,ans*mul,i);
        }
    }
    int main()
    {
    	freopen("in.txt","r",stdin);
        cin>>n>>k;
        for(int i=1;i<=n;i++)
        {
            cin>>ch;
            a[i]=ch-'0';
        }
        dfs(0,1,0);//初始值处理   
        cout<<maxx;
    }
    
    
    

      这种做法来自sumyt,原文:

    题解 P1018 【乘积最大】 - sunyt 的博客 - 洛谷博客
    https://www.luogu.org/blog/user17407/solution-p1018

    void dfs(三个已插入的乘号个数,当前乘积,上一个插入的乘号的位置)中

    第三个形参的说明:比如在1231中插了一个变成:1*231,那么该形参表示的是“*”左边的1的位置

    for(int j=last+1;j<i;j++)
    {
    mul+=a[j]; mul*=10;
    } mul+=a[i];
    mul表示上一乘号到刚插入的这个乘号之间的数字。
    好啦解释(ban yun)完毕。
  • 相关阅读:
    javascript操作样式
    JavaScript开发
    JavaScript开发
    JavaScript开发
    网页设计
    会员登录界面设计
    用表格模拟实现一个菜鸟教程的网站遇到的问题
    数据库---数据控制语言(DCL)
    数据库---数据库查询的各种子句
    数据库表--增删改查的操作实例
  • 原文地址:https://www.cnblogs.com/Neptune0/p/11379202.html
Copyright © 2011-2022 走看看