hdu 3022 Sum of Digits ural 1658. Sum of Digits 夜

http://acm.hdu.edu.cn/showproblem.php?pid=3022

http://acm.timus.ru/problem.aspx?space=1&num=1658

给你 n 和 m 问能不能找到一个一百位以内的数

使得每位的和为 n  每位平方的和为 m

又是看了别人的思路呀 伤不起呀 自己的能力还是不够呀

digits[i][j] 表示 n 为i m为j 时最少位数

num[i][j] 表示最少位数时 最靠前一位是几

让后以位数最小优先 在以考前位越小越好优先 dp

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<stack>
#include<algorithm>
#define LL long long

using namespace std;

const int N=901;
const int M=8101;
int digits[N][M];
int num[N][M];

int dp(int a,int b)
{
    if(digits[a][b]!=-1)
    return digits[a][b];
    if(a==0||b==0)
    {
        if(a==0&&b==0)
        digits[a][b]=0;
        else
        digits[a][b]=101;
        return digits[a][b];
    }
    if(a>b)
    {
        digits[a][b]=101;
        return digits[a][b];
    }
    digits[a][b]=101;
    int k;
    for(int i=1;i<=9;++i)
    {
        if(a-i>=0&&b-i*i>=0)
        {
            k=dp(a-i,b-i*i);
            if(k+1<digits[a][b])
            {
                num[a][b]=i;
                digits[a][b]=k+1;
            }
        }
    }
    return digits[a][b];
}
void print(int i,int a,int b)
{
    printf("%d",num[a][b]);
    if(i>1)
    print(i-1,a-num[a][b],b-num[a][b]*num[a][b]);
}
int main()
{
    memset(digits,-1,sizeof(digits));
    memset(num,-1,sizeof(num));
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d %d",&n,&m);
        int k=101;
        if(n<=m&&n<N&&m<M)
        k=dp(n,m);
        if(k==101)
        printf("No solution");
        else
        {
            print(k,n,m);
        }
        printf("\n");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2605957.html