题目描述
这是一道原题用来避免大家爆0。
下面这张图给出了上课讲过的东西。
所以如果你上课没听的话就可能要凉了。
现在你有x根火柴棒。
LYK:“这上课讲过,不是全拼1就行了嘛!”
“但我现在想知道最小的数字了!”
“呵”
输入格式(stick.in)
一个数x,表示有x根火柴棒。
输出格式(stick.out)
一个数,表示拼出的t,要求t尽可能小,有两个要求。
①:用完x根火柴棒。
②:t没有前导0。
输入样例
15
输出样例
108
样例解释
108共需要2+6+7=15根,且是符合要求的最小的没有前导0的数字。
数据范围
对于30%的数据x<=10。
对于60%的数据x<=20。
对于100%的数据1<x<=100。
很明显是个背包,不断的尝试往前面dp出来的数后面加数字,最后取min即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
long long d[105],f[11],n;
int main()
{
scanf("%d",&n);
f[0]=6,f[1]=2,f[2]=5,f[3]=5,f[4]=4,f[5]=5;
f[6]=6,f[7]=3,f[8]=7,f[9]=6;
d[2]=1,d[3]=7,d[4]=4,d[5]=2,d[6]=6,d[7]=8;
for(int i=8;i<=n;i++)
{
d[i]=d[i-f[0]]*10;
for(int j=0;j<=9;j++)
{
if(d[i-f[j]]!=0)
{
d[i]=min(d[i],d[i-f[j]]*10+j);
}
}
}
if(n==6)cout<<"0"; else cout<<d[n];//这里要特判,n=6直接出0,dp[6]不能为0,dp的过程是往一个数后面接数,题目不允许前导0的存在,所以必须特判
}