URAL1658 Sum of Digits(DP)

本文介绍了一个有趣的问题:给定各位数字之和S1与各位平方之和S2,如何找到满足这些条件的最小数字。文章详细阐述了使用动态规划解决这一问题的方法,并提供了一个高效的算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:有一个不多于100位的数字,满足各位之和为S1,各位平方之和为S2,求满足该条件的最小数字

思路:首先要理解,S1<=900,为什么呢?假设每一位的数字都取9,那么100位之和就为900,不能再多了,同理,S2<=8100。然后就可以将这个问题泛化为一个二维完全背包问题,有1-9种物品可以任意选,最后的价值是它们的和,体积是它们的平方和,那么DP[i][j]可以表示为要取i价值,j体积最少要取多少件物品。DP方程见代码


#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 100000
#define LL long long
int cas=1,T;
#define INF 1000000
int dp[901][8110];
int a[10];
int num[910];
int pos;
void Print(int s1,int s2)
{
	if (!s1 && !s2)
		return;
	for (int i = 1;i<=9;i++)
	{
		if (dp[s1-i][s2-a[i]] == dp[s1][s2]-1)
		{
			num[pos++] =i;
			Print(s1-i,s2-a[i]);
			return;
		}
	}
}
int main()
{
	for (int i = 1;i<=9;i++)
		a[i]=i*i;
	for (int i = 0;i<=900;i++)
		for (int j = 0;j<=8100;j++)
			dp[i][j]=1000000;

	dp[0][0]=0;
	for (int i = 1;i<=9;i++)
		for (int j = i;j<=900;j++)
			for (int k = a[i];k<=8100;k++)
				dp[j][k] = min(dp[j][k],dp[j-i][k-a[i]]+1);

	//freopen("in","r",stdin);
	scanf("%d",&T);
	while (T--)
    {
		int s1,s2;
		scanf("%d%d",&s1,&s2);
		if (s1 > s2 || s1>900 || s2 > 8100)
			printf("No solution\n");
		else
		{
			if (dp[s1][s2]>100)
				printf("No solution\n");
			else
			{
				pos = 0;
				Print(s1,s2);
                for (int i = 0;i<pos;i++)
					printf("%d",num[i]);
				printf("\n");
			}
		}
	}
	//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
	return 0;
}

Description

Petka thought of a positive integer n and reported to Chapayev the sum of its digits and the sum of its squared digits. Chapayev scratched his head and said: "Well, Petka, I won't find just your number, but I can find the smallest fitting number." Can you do the same?
 

Input

The first line contains the number of test cases t (no more than 10000). In each of the following t lines there are numbers s1 and s2 (1 ≤ s1, s2 ≤ 10000) separated by a space. They are the sum of digits and the sum of squared digits of the number n.
 

Output

For each test case, output in a separate line the smallest fitting number n, or "No solution" if there is no such number or if it contains more than 100 digits.
 

Sample Input

4 9 81 12 9 6 10 7 9
 

Sample Output

9 No solution 1122 111112
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值