1 条题解

  • 0
    @ 2026-5-9 16:29:27

    Problem

    给定一个用火柴棍摆出的 nn 位的数,问在最多移动 mm 次的情况下,能摆出的最大数。

    Solution

    分成两部分,数字 11 被摆出需要的火柴棍最少,所以优先加位肯定是最好的,不会使答案变小。
    这是贪心。
    然后是一个数位 Dp,求出最多有多少火柴棍可以拆出来,用来加位。
    fp,ctf_{p, ct} 表示从高往低到第 pp 位,已经确定用途的火柴棍有 ctct 根所需的火柴棍数。
    于是 dfs,再从大往小枚举用来加位的火柴棍数,判断最终所需总火柴棍数是否不超过 mm 即可。
    输出方案过程类似。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 510, M = 5010, inf = 0x3f3f3f3f;
    
    int n, m;
    string str;
    int f[N][M];
    int trans[10][10] = {
    	{0, 4, 2, 2, 3, 2, 1, 3, 0, 1},
    	{0, 0, 1, 0, 0, 1, 1, 0, 0, 0},
    	{1, 4, 0, 1, 3, 2, 1, 3, 0, 1},
    	{1, 3, 1, 0, 2, 1, 1, 2, 0, 0},
    	{1, 2, 2, 1, 0, 1, 1, 2, 0, 0},
    	{1, 4, 2, 1, 2, 0, 0, 3, 0, 0},
    	{1, 5, 2, 2, 3, 1, 0, 4, 0, 1},
    	{0, 1, 1, 0, 1, 1, 0, 0, 0, 0},
    	{1, 5, 2, 2, 3, 2, 1, 4, 0, 1},
    	{1, 4, 2, 1, 2, 1, 1, 3, 0, 0}
    };
    int cnt[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
    
    int dfs(int p, int ct)
    {
    	if (ct > m) return inf;
    	if (!p) return ct ? inf : 0;
    	if (~f[p][ct]) return f[p][ct];
    	
    	f[p][ct] = inf;
    	for (int i = 9; ~i; i -- )
    	{
    		int tmp = dfs(p - 1, ct + cnt[i] - cnt[str[p]]) + trans[str[p]][i];
    		f[p][ct] = min(f[p][ct], tmp);
     	}
     	
     	return f[p][ct];
    }
    
    void put(int p, int ct)
    {
    	while (p)
    	{
    		for (int i = 9; ~i; i -- )
    		{
    			int t = dfs(p - 1, ct + cnt[i] - cnt[str[p]]) + trans[str[p]][i];
    			if (t <= m)
    			{
    				cout << i;
    				m -= trans[str[p]][i];
    				ct += cnt[i] - cnt[str[p]];
    				p -- ;
    				break;
    			}
    		}
    	}
    }
    
    signed main()
    {
    	cin >> str >> m;
    	
    	n = str.size();
    	reverse(str.begin(), str.end());
    	str = " " + str;
    	memset(f, -1, sizeof f);
    	for (int i = 1; i <= n; i ++ ) str[i] -= '0';
    	for (int i = m; i > 1; i -- )
    	{
    		if (dfs(n, i) <= m)
    		{
    			int t = i;
    			if (t & 1) cout << "7", t -= 3;
    			while (t) cout << "1", t -= 2;
    			put(n, i);
    			return 0;
    		}
    	}
    	
    	put(n, 0);
    	
    	return 0;
    }
    
    • 1

    信息

    ID
    4989
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者