这题卡了挺久了 昨天试着用类似dfs的方法直接TLE在第二组 看了下题解,,发现s1,s2的范围是个幌子。。100位最大的s1900 s28100 觉得s1s2太大不敢开二维。。
这样就简单了 类似背包 dp[s1][s2]表示组成s2s2最少的位数 其实就是装进去多少个数字 正好把s1s2装满
把DP部分预处理之后放在外面 不然会超时
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stdlib.h> 5 #include<algorithm> 6 using namespace std; 7 #define INF 0xfffffff 8 int s1,s2; 9 int dp[920][8120]; 10 int path[110],flag; 11 void dfs(int ss1,int ss2,int u,int v) 12 { 13 path[u] = v; 14 if(flag) return ; 15 int i; 16 if(u==1&&ss1==0&&ss2==0) 17 { 18 flag = 1; 19 for(i = dp[s1][s2] ; i>=1; i--) 20 printf("%d",path[i]); 21 puts(""); 22 return ; 23 } 24 if(ss1<=0||ss2<=0) 25 return ; 26 u--; 27 for(i = 1; i <= 9 ; i++) 28 { 29 if(ss1-i<0||ss2-i*i<0) 30 continue; 31 if(dp[ss1-i][ss2-i*i]+1==dp[ss1][ss2]) 32 dfs(ss1-i,ss2-i*i,u,i); 33 if(flag) break; 34 } 35 } 36 int main() 37 { 38 int i,j,g,t; 39 scanf("%d",&t); 40 for(i = 0; i <= 900 ; i++) 41 for(j = 0 ; j <= 8100 ; j++) 42 dp[i][j] = INF; 43 dp[0][0] = 0; 44 for(i = 1 ; i <= 9 ; i++) 45 for(j = i ; j <= 900 ; j++) 46 for(g = i*i ; g <= 8100 ; g++) 47 dp[j][g] = min(dp[j][g],dp[j-i][g-i*i]+1); 48 while(t--) 49 { 50 scanf("%d%d",&s1,&s2); 51 if(s1>900||s2>8100) 52 { 53 printf("No solution "); 54 continue; 55 } 56 flag = 0; 57 if(dp[s1][s2]==INF||dp[s1][s2]>100) 58 { 59 printf("No solution "); 60 } 61 else 62 { 63 for(i =1; i <= 9 ; i++) 64 { 65 if(s1-i<0||s2-i*i<0) 66 continue; 67 if(dp[s1-i][s2-i*i]+1==dp[s1][s2]) 68 dfs(s1-i,s2-i*i,dp[s1][s2],i); 69 if(flag) break; 70 } 71 } 72 } 73 return 0; 74 }