UPC-Match Matching(完全背包dp+字符串)

但因热爱 愿迎万难。

问题 M: Match Matching

时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]

题目描述

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.

样例输入 Copy

20 4
3 7 8 4

样例输出 Copy

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.

题意: 给定n根火柴,m个数,每个数代表能够使用的火柴的值,比如2表示能够使用1这根火柴,问用n根这m个数代表的火柴能够拼成的数字最大是多少。(有点混乱)

思路:
这是个很典型的 完全背包叭,再结合贪心的思想,先比较长度,相同长度再比较大小。
思路不难想,重要的是如何实现。
下面是开字符串数组的做法,用到了一个函数to_string将数字转化成字符串,再利用字符串可以直接相加的原则,直接进行状态转移。
代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
int a[maxn],b[maxn];
int n,m;
string dp[maxn];
int c[10] = {0, 2, 5, 5, 4, 5, 6, 3, 7, 6};
int main(){
   scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++) scanf("%d",&a[i]);
    //  dp[0]="";//初始化(可忽略)
    ///cout<<dp[0]<<endl;
    for(int i=1;i<=n;i++){
            //dp[i]="";(可忽略)
            for(int j=0;j<m;j++){
                if((i-c[a[j]])<0||((i-c[a[j]])!=0 &&dp[i-c[a[j]]]=="")) continue;//此状态无法由其他状态转移过来
                   /// dp[i]=max(dp[i],dp[i-c[a[j]]]+to_string(a[j]));
                if(dp[i].size()<dp[i-c[a[j]]].size()+1)//先选择最长的
                    dp[i]=dp[i-c[a[j]]]+to_string(a[j]);
                else if(dp[i].size()==dp[i-c[a[j]]].size()+1)//相同长度再选择最大的
                    dp[i]=max(dp[i],dp[i-c[a[j]]]+to_string(a[j]));
            }
        }
        cout<<dp[n]<<endl;
    return 0;
}

好敷衍的题解
您也可以去看另外的做法传送门
补一波作业去
3月Flag:改掉拖延!

posted @ 2020-03-06 12:21  OvO1  阅读(68)  评论(0编辑  收藏  举报