题目:给定一个数,,求它最少可以用多少个包含字符串"61"的数字来表示,并输出这些数。
分析:对于大于6161的任何一个整数,都有如下表示
对于小于1616的数,直接背包即可。
代码:
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
typedef long long LL;
const int N = 10005;
const int INF = 0x3f3f3f3f;
int dp[N];
int pre[N];
int v[N];
bool check(LL n)
{
int a[20];
int cnt = 0;
while(n)
{
a[cnt++] = n % 10;
n /= 10;
}
for(int i = 0;i < cnt-1;i++)
if(a[i] == 1 && a[i+1] == 6)
return true;
return false;
}
void ouput(int n)
{
if(pre[n] != 0) ouput(pre[n]);
printf(" %d",n - pre[n]);
}
int main()
{
int T;
LL n;
scanf("%d",&T);
int num = 0;
for(int i = 1;i <= 6161;i++)
if(check(i))
v[num++] = i;
for(int i = 0;i < N;i++)
dp[i] = INF;
dp[0] = 0;
pre[0] = -1;
for(int i = 1;i < N;i++)
{
for(int j = 0;j < num && v[j] <= i;j++)
{
if(dp[i] > dp[i-v[j]] + 1)
{
dp[i] = dp[i-v[j]] + 1;
pre[i] = i - v[j];
}
}
}
while(T--)
{
scanf("%lld",&n);
if(check(n))
{
printf("1 %lld\n",n);
continue;
}
if(n >= 6161)
{
LL ans1 = 61;
LL ans2 = 6100;
n -= 6161;
ans2 += n % 100;
ans1 += (n / 100) * 100;
printf("2 %lld %lld\n",ans1,ans2);
continue;
}
if(dp[n] == INF)
{
printf("0\n");
continue;
}
printf("%d",dp[n]);
ouput(n);
printf("\n");
}
return 0;
}