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; }