题目描述
Find the largest integer that can be formed with exactly N matchsticks, under the following conditions:
Every digit in the integer must be one of the digits A1,A2,...,AM(1≤Ai≤9).
The number of matchsticks used to form digits 1,2,3,4,5,6,7,8,9 should be 2,5,5,4,5,6
,3,7,6, respectively.
Constraints
·All values in input are integers.
·2≤N≤104
·1≤M≤9
·1≤Ai≤9
·Ai are all different.
·There exists an integer that can be formed by exactly N matchsticks under the conditions.
输入
Input is given from Standard Input in the following format:
N M
A1 A2 ... AM
输出
Print the largest integer that can be formed with exactly N matchsticks under the conditions in the problem statement.
样例输入
20 4 3 7 8 4
样例输出
777773
提示
The integer 777773 can be formed with 3+3+3+3+3+5=20 matchsticks, and this is the largest integer that can be formed by 20 matchsticks under the conditions.
题目大意:规定用火柴摆数字的样子,从 1 ~ 9 所需要的火柴分别为2,5,5,4,5,6,3,7,6,现在给出 m 个不同的且小于十的数字,问恰好用完 n 根火柴,使得摆出的数字最大,且该数字必须使用提供的 m 个数字,问最大可以拼出的数字能有多大
题目分析:一开始感觉是先贪心后暴力,但看到需要恰好用掉 n 个火柴感觉有点蹊跷,加上有 m 个数字的限制,使得贪心并不是如此简单,后来发现 n 比较小,且必须要恰好用完 n ,使得结果最大,那不就是一个最优性问题,用dp来解决,恰好用完让我想到了完全背包,这样一来只要重载一下MAX函数,用字符串作为dp数组,花费为每个数字所需要的火柴数,价值为每个数字本身,转移一遍就好了,注意初始化
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int N=1e5+100;
int a[N];
string dp[N];
string val="0123456789";
int cost[10]={0,2,5,5,4,5,6,3,7,6};
string MAX(string a,string b)
{
if(a.size()>b.size())
return a;
if(a.size()<b.size())
return b;
return a>b?a:b;
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d",a+i);
for(int i=0;i<=n;i++)
dp[i]="-";
dp[0]="";
for(int i=0;i<=n;i++)
{
if(dp[i]=="-")
continue;
for(int j=1;j<=m;j++)
if(i+cost[a[j]]<=n)
dp[i+cost[a[j]]]=MAX(dp[i+cost[a[j]]],dp[i]+val[a[j]]);
}
cout<<dp[n]<<endl;
return 0;
}