probelm D 大数+组合dp

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define maxn 100
struct Bignum
{
  int num[maxn];
  int len;
};
Bignum f[33][33];
Bignum Add(Bignum &a,Bignum &b)
{
    Bignum c;
    int len=(a.len>b.len)?a.len:b.len;
    memset(c.num,0,sizeof(c.num));
    for(int i=0;i<len;i++)
    {
     c.num[i]+=(a.num[i]+b.num[i]);
     if(c.num[i]>=10)
     {
      c.num[i+1]++;
      c.num[i]-=10;
     }
    }
    if(c.num[len])len++;
    c.len=len;
    return c;
}
Bignum Mult(Bignum &a,int b)
{
    Bignum c;
    int len=a.len;
    memset(c.num,0,sizeof(c.num));
    for(int i=0;i<len;i++)
    {
        c.num[i]+=(a.num[i]*b);
        if(c.num[i]>=10)
        {
            c.num[i+1]=c.num[i]/10;
            c.num[i]%=10;
        }
    }
    while(c.num[len]>0)
    {
            c.num[len+1]=c.num[len]/10;
            c.num[len++]%=10;
    }
    c.len=len;
    return c;
}
void print(Bignum &a)
{
    for(int i=a.len-1;i>=0;i--)
        printf("%d",a.num[i]);
    putchar(10);
}
int main()
{
   int len;
    int P,L,K;
    Bignum  ans;
    while(~scanf("%d%d%d",&P,&L,&K))
    {
    for(int i=0;i<33;i++)
        for(int j=0;j<33;j++)
    {
         memset(f[i][j].num,0,sizeof (f[i][j].num));
         f[i][j].len=0;
    }
    f[1][1].len=1;
    f[1][1].num[0]=1;
    int x=P-1;
    int len=0;
    while(x)
    {
        f[1][0].num[len++]=x%10;
        x/=10;
    }
    f[1][0].len=len;
    for(int i=2;i<=L;i++)
    {
         ans.len=0;
         memset(ans.num,0,sizeof(ans.num));
        for(int j=K-1;j>=1;j--)
        {
            f[i][j]=f[i-1][j-1];
            ans=Add(ans,f[i][j]);
        }
        Bignum k=Add(ans,f[i-1][K-1]);
        f[i][0]=Mult(k,P-1);
    }
    ans.len=1;
    memset(ans.num,0,sizeof(ans.num));
    ans.num[0]=0;
    for(int i=0;i<=K-1;i++)
    {
       ans=Add(ans,f[L][i]);
    }
    for(int i=ans.len-1;i>=0;i--)
     printf("%d",ans.num[i]);
    putchar(10);
    }
    return 0;
}
帮我看一下关于原先那道题这个代码有什么问题:#include<bits/stdc++.h> using namespace std; const int MAXN = 105; int T; int N, K; int a[MAXN], dp[MAXN][MAXN];//dp[i][j]表示a[i]->a[j]位生成子序列需要的print数量 int main(){ cin >> T; while( T -- ){ cin >> N >> K; memset( a, 0, sizeof( a ) ); memset( dp, 0, sizeof( dp ) ); for( int i = 1; i <= N; i ++ ){ cin >> a[i]; dp[i][i] = 1; } for( int len = 2; len <= N; len ++ ){ for( int i = 0; i <= N - len; i ++ ){ int j = i + len - 1; for( int k = i; k < j; k ++ ) dp[i][j] = min( dp[i][j], dp[i][k] + dp[k + 1][j] );//转移 for( int l = 1; l <= len; l ++ ){//去除重复的( j - i + 1 ) / l if( len % l != 0 ) continue; bool flag = true; for( int ll = i; ll <= j; ll ++ ){ int cnt = i + ( ll - i ) % l; if( a[ll] != a[cnt] ){ flag = false; break; } } if( flag ) dp[i][j] = min( dp[i][j], dp[i][i + l - 1] ); } } } cout << ( dp[0][N - 1] <= K ? "YES" : "NO" ) << endl; } return 0; }题面如下:Bessie 正在学习使⽤⼀种简单的编程语⾔进⾏编程。她⾸先定义⼀个合法的程序,然后执⾏该程序以产⽣⼀些输出序列。 定义: ⼀个程序是⼀个⾮空的语句序列。 ⼀个语句的形式或者是 "PRINT ",其中 是⼀个整数,或者是 "REP ",随后是⼀个程序,随后是 “END”,其中 是⼀个不⼩于 1 的整数。 执⾏: 执⾏⼀个程序将依次执⾏其语句。 执⾏语句 "PRINT " 将使 追加到输出序列中。 执⾏以 "REP " 开始的语句将依次执⾏内部程序共 次。 Bessie 知道如何编写的⼀个程序⽰例如下。 REP 3 PRINT 1 REP 2 PRINT 2 END END 该程序输出序列 。 Bessie 想要输出⼀个包含 ( )个正整数的序列。Elsie 挑战她使⽤不超过 ( )个 “PRINT” 语句。注意,Bessie 可 以使⽤任意数量的 “REP” 语句。同时注意,序列中的每个正整数都不超过 。 对于 ( )个独⽴的测试⽤例中的每⼀个,求 Bessie 是否可以编写⼀个程序,使⽤⾄多 个 “PRINT” 语句输出给定的序列。 输⼊格式 从 print.in 中读取数据 输⼊的第⼀⾏包含 。 每⼀个测试⽤例的第⼀⾏包含空格分隔的两个整数 和 。 每⼀个测试⽤例的第⼆⾏包含⼀个由 个空格分隔的正整数组成的序列,每个数都不超过 ,为 Bessie 想要产⽣的序列。 输出格式 将答案输出到 print.out 中 对于每⼀个测试⽤例输出⼀⾏,包含 “YES” 或 “NO”(⼤⼩写敏感)。 输⼊输出样例 #1 输⼊ #1 2 1 1 1 4 1 1 1 1 1 c c o o c c o o [1, 2, 2, 1, 2, 2, 1, 2, 2] N 1 ≤ N ≤ 100 K 1 ≤ K ≤ 3 K T 1 ≤ T ≤ 100 K T N K N K 输出 #1 YES YES 输⼊输出样例 #2 输⼊ #2 11 4 2 1 2 2 2 4 2 1 1 2 1 4 2 1 1 2 2 6 2 1 1 2 2 1 1 10 2 1 1 1 2 2 1 1 1 2 2 8 3 3 3 1 2 2 1 2 2 9 3 1 1 2 2 2 3 3 3 3 16 3 2 2 3 2 2 3 1 1 2 2 3 2 2 3 1 1 24 3 1 1 2 2 3 3 3 2 2 3 3 3 1 1 2 2 3 3 3 2 2 3 3 3 9 3 1 2 2 1 3 3 1 2 2 6 3 1 2 1 2 2 3 输出 #2 YES NO YES NO YES YES YES YES YES NO NO 说明/提⽰ 样例 1 解释: 对于第⼆个测试⽤例,以下代码使⽤了 个 “PRINT” 语句输出了序列 。 REP 4 PRINT 1 END 样例 2 解释: 对于第⼀个测试⽤例,以下代码使⽤了 个 “PRINT” 语句输出了序列 。 1 [1, 1, 1, 1] 2 [1, 2, 2, 2] PRINT 1 REP 3 PRINT 2 END 对于第⼆个测试⽤例,答案是 “NO”,因为使⽤不超过 个 “PRINT” 语句输出序列 是不可能的。 对于第六个测试⽤例,以下代码使⽤了 个 “PRINT” 语句输出了序列 。 REP 2 PRINT 3 END REP 2 PRINT 1 REP 2 PRINT 2 END END 测试点 : 。 测试点 : 。 测试点 :没有额外限制。 2 [1, 1, 2, 1] 3 [3, 3, 1, 2, 2, 1, 2, 2] 3 K = 1 4 ∼ 7 K ≤ 2 8 ∼ 13
09-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值