NYOJ746 整数划分(搜索||DP)

来源:互联网 发布:淘宝店卖家开店时间 编辑:程序博客网 时间:2024/05/29 04:59

整数划分(四)

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
描述

       暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近遇到了一个难题,让他百思不得其解,他非常郁闷。。亲爱的你能帮帮他吗?

      问题是我们经常见到的整数划分,给出两个整数 n , m ,要求在 n 中加入m - 1 个乘号,将n分成m段,求出这m段的最大乘积

输入
第一行是一个整数T,表示有T组测试数据
接下来T行,每行有两个正整数 n,m ( 1<= n < 10^19, 0 < m <= n的位数);
输出
输出每组测试样例结果为一个整数占一行
样例输入
2111 21111 2
样例输出
11121

数据比较小,想着搜索先来一发,居然0ms,数据有点水

搜索:枚举每一种组合,刷新m段时的最小值

#include<stdio.h>#include<string.h>#include<algorithm>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;typedef long long ll;const int N=20;ll sum[N][N];char s[N];ll n,maxx,m;void dfs(ll r,ll ans,ll step){    if(step==m)    {        maxx=max(maxx,ans);        return;    }    for(ll i=1;i<=n-m+1;i++)    {        if(r+i<=n)        {            dfs(r+i,ans*sum[r+1][r+i],step+1);        }    }}int main(){    ll t;    scanf("%lld",&t);    while(t--)    {        mem(sum,0);        maxx=0;        scanf("%s %lld",s+1,&m);         n=strlen(s+1);        for(ll i=1; i<=n; i++)        {            sum[i][i]=s[i]-'0';            for(ll j=i+1; j<=n; j++)            {                sum[i][j]=sum[i][j-1]*10+s[j]-'0';            }        }        dfs(0,1,0);        printf("%lld\n",maxx);    }}
区间DP:

dp[i][j]表示1~i被分成j段的最大值

#include<stdio.h>#include<string.h>#include<algorithm>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;typedef long long ll;const int N=20;ll sum[N][N],dp[N][N];char s[N];ll n,maxx,m;int main(){    ll t;    scanf("%lld",&t);    while(t--)    {        mem(sum,0);        mem(dp,0);        scanf("%s %lld",s,&m);         n=strlen(s);        for(ll i=0; i<n; i++)        {            sum[i][i]=s[i]-'0';            for(ll j=i+1; j<n; j++)            {                sum[i][j]=sum[i][j-1]*10+s[j]-'0';            }        }        for(ll i=0;i<n;i++)        {            dp[i][1]=sum[0][i];            for(ll j=2;j<=m;j++)            {                for(ll k=j-2;k<i;k++)                {                    dp[i][j]=max(dp[i][j],dp[k][j-1]*sum[k+1][i]);                }            }        }        printf("%lld\n",dp[n-1][m]);    }}





原创粉丝点击