【UVa】【DP】12105 Bigger is Better

本文解析了UVa12105题目的解决方案,采用数位DP的方法,在不超过N根火柴的前提下,构造一个尽可能大的、能被M整除的正整数。文章详细介绍了状态定义、状态转移方程,并提供了简洁的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UVa 12105 Bigger is Better

题目

◇题目传送门◆(由于UVa较慢,这里提供一份vjudge的链接)
◇题目传送门(vjudge)◆

题目大意

使用不超过 N N 根的火柴摆出一个尽量大的、能够被M整除的正整数。数字的摆放方法如下图所示:

思路

一道极其明显的数位DP。。。

相信大家都看了紫书的两种做法(但是我根本没有看懂)。但是我在这里将给出一个极其简洁的做法。

所以我们可以定义状态 f[i][j] f [ i ] [ j ] 为使用不超过 i i 根火柴,拼出来的数模M j j 的数的最长长度。

因为在火柴根数相等的情况下,拼出来的数越长,数就越大。

则极易列出状态转移方程:

f[i][j]=max{f[ic(d)][(j×10+d)modM]+1}

其中 d d 为当前往数的末尾中添加的一位数字,c(d)表示拼出数字 d d 需要的火柴数量。

因为要输出方案,所以计算时记录一下路径,逆序输出即可。

是不是很简洁?:-)

正解代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int Maxn=100;
const int Maxm=3000;
const int ned[]={6,2,5,5,4,5,6,3,7,6};

int N,M;
int f[Maxn+5][Maxm+5];
int p[Maxn+5][Maxm+5];

int main() {
    #ifdef LOACL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int cas=0;
    while(scanf("%d %d",&N,&M)==2) {
        memset(f,-1,sizeof f);
        memset(p,-1,sizeof p);
        for(int i=0;i<=N;i++)
            for(int j=0;j<M;j++) {
                if(j==0)f[i][j]=0;
                for(int d=9;d>=0;d--)//注意逆序枚举!!!
                    if(i>=ned[d]) {
                        int t=f[i-ned[d]][(j*10+d)%M];
                        if(t>=0&&t+1>f[i][j]) {//只有当状态合法时才转移
                            f[i][j]=t+1;
                            p[i][j]=d;
                        }//记录当前所选中的数字d
                    }
            }
        printf("Case %d: ",++cas);
        if(p[N][0]<0) {
            printf("-1");
        } else {
            int i=N,j=0;//逆序输出
            for(int d=p[i][j];d>=0;d=p[i][j]) {
                printf("%d",d);
                i-=ned[d];
                j=(j*10+d)%M;
            }
        }
        puts("");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值