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;

}

  

 

你可能感兴趣的:(git)