1月4号 D题 小信拼数字

时间:1s 空间:256M

题目描述:

小信有n根木棍,他想拼出只包含给定的m种数字中的至少一种数字的数字串。

已知数字1,2,3,4,5,6,7,8,9分别需要2,5,5,4,5,6,3,7,6根火柴。要求n根木棍全部都用完且拼成的数字最大,输出这个数字。保证答案存在。

输入格式:

第一行包含两个整数 n,m,表示木棍数量和给定数字种类数。

第二行包含m个数a1,a2...am,表示给定的数字,保证数字互不相同。

输出格式:

输出一串数字表示答案。

样例1输入:

20 4

3 4 8 7

样例1输出:

777773

约定与提示:

对于100%的数据,2≤n≤104,1≤m,ai≤9,

样例解释:

777773 需要 5∗3+1∗5=20根木棍。

题意:

用n根火柴,可以拼m种数字,用这些火柴拼出的数字要尽可能的大

思路:

此题是完全背包,而代价(v[i])就是用去的火柴数,问题是这道题一个难点在于怎么样数字更大,那我们可以先比位数,比完位数,比各个位的大小,普通完全背包转移方程为:

f[j]=max(f[j],f[j-v[i]]+w[i])

将此状态转移方程改成按位数比较(改为高精度),此题要恰好用完,就是恰好装满背包所以要把初始化改成0。

代码:

#include<bits/stdc++.h>
using namespace std;
long long a[10005],len=0,times;
long long f[10005];
int quantity[10]={0,2,5,5,4,5,6,3,7,6};//每个数字所需火柴数因为数组从0开始记所以有0 
int cmp(int x,int y) {
    return x>y;
}
int main(){
    int n,m;
    cin>>n>>m;
    memset(f,-1,sizeof(f));
    for(int i=1;i<=m;i++) {
        cin>>a[i];//ai就代表那些数 
    }
    sort(a+1,a+m+1,cmp);
    f[0]=0;//恰好装满初始化0 
    for(int i=1;i<=m;i++) {
        for(int j=quantity[a[i]];j<=n;j++) {
            f[j]=max(f[j],f[j-quantity[a[i]]]+1);//完全背包转移方程为:f[j]=max(f[j],f[j-v[i]]+w[i]),v[i]所代表的代价,实际就是用去的火柴价值就是让位数加一 
        }
    }
    while(n>=0){
        for(int i=1;i<=m;i++){//能选m种 
            if(f[n]==f[n-quantity[a[i]]]+1){//f[总量]=f[总量-火柴代表的量]+1(ai代表的是那种数字,quantity代表这种数字需要的火柴量) 
                if(n-quantity[a[i]]>=0){//如果不做此判断,会有一些数也满足上个条件,但是减去他就会比总量小出现bug 
                n-=quantity[a[i]];//总数减去代价
                    cout<<a[i];
                    break;
                    times=i;
                }
            } 
        }
        if(n-quantity[a[times]]==0){//因为如果做了 if(n-quantity[a[i]]>=0)的判断答案正确但会陷入死循环n永远不会小于0,所以用times记住满足条件的时候是的几个数,然后判断总量减去那个数对应的火柴数是否等于0,是的话就跳出循环 
            break;
        }
    }
    return 0; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值