中石油训练赛 - Match Matching(完全背包)

题目描述

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;
}
发布了672 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/104685967