1073. Square Country
Time Limit: 1.0 second
Memory Limit: 64 MB
Memory Limit: 64 MB
There
live square people in a square country. Everything in this country is
square also. Thus, the Square Parliament has passed a law about a land.
According to the law each citizen of the country has a right to buy
land. A land is sold in squares, surely. Moreover, a length of a square
side must be a positive integer amount of meters. Buying a square of
land with a side a one pays a2 quadrics (a local currency) and gets a square certificate of a landowner.
One citizen of the country has decided to invest all of his N
quadrics into the land. He can, surely, do it, buying square pieces
1 × 1 meters. At the same time the citizen has requested to minimize an
amount of pieces he buys: "It will be easier for me to pay taxes," — he
has said. He has bought the land successfully.
Your task is to find out a number of certificates he has gotten.
Input
The only line contains a positive integer N ≤ 60 000 , that is a number of quadrics that the citizen has invested.
Output
The only line contains a number of certificates that he has gotten.
Sample
input | output |
---|---|
344 |
3 |
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #define MAX 60000+1 6 using namespace std; 7 int dp[MAX] ; 8 int main(){ 9 int n; 10 cin >> n; 11 fill(dp,dp+MAX,1<<30); 12 dp[0] = 0; 13 for(int i = 1; i <=(int)sqrt(n); i ++ ){ 14 for(int j = i*i; j <= n; j ++ ){ 15 dp[j] = min(dp[j],dp[j-i*i]+1); 16 } 17 } 18 cout<<dp[n]<<endl; 19 return 0; 20 }
//回溯法
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #define MAX 250 using namespace std; int minnum = 1<<30; bool BackTrack(int num,int n){ if(n == 0) minnum = min(num,minnum); else{ int node[250],len,k; for(len = 0,k = (int)sqrt(n); k > 0; k--,len++) node[len]=k; for(int i = 0; i < len; i ++ ) if(num + 1 < minnum){ if(!BackTrack(num+1,n - node[i]*node[i])) return true; } else return false; } return true; } int main(){ int n; cin >> n; BackTrack(0,n); cout<<minnum<<endl; return 0; }
对两种回溯进行测试,但下面这种回溯会超时,不知道为什么,求解答
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #define MAX 250 using namespace std; int minnum = 1<<30; void BackTrack(int num,int n){ if(num >= minnum) return; if(n == 0) minnum = min(num,minnum); else{ int node[250],len,k; for(len = 0,k = (int)sqrt(n); k > 0; k--,len++) node[len]=k; for(int i = 0; i < len; i ++ ) BackTrack(num+1,n - node[i]*node[i]); } } int main(){ int n; cin >> n; BackTrack(0,n); cout<<minnum<<endl; return 0; }
测试代码
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #define MAX 250 using namespace std; int minnum = 1<<30; int minnum1 = 1<<30; void BackTrack(int num,int n){ if(num >= minnum) return; if(n == 0) minnum = min(num,minnum); else{ int node[250],len,k; for(len = 0,k = (int)sqrt(n); k > 0; k--,len++) node[len]=k; for(int i = 0; i < len; i ++ ) BackTrack(num+1,n - node[i]*node[i]); } } bool BackTrack1(int num,int n){ if(n == 0) minnum1 = min(num,minnum1); else{ int node[250],len,k; for(len = 0,k = (int)sqrt(n); k > 0; k--,len++) node[len]=k; for(int i = 0; i < len; i ++ ) if(num + 1 < minnum1){ if(!BackTrack1(num+1,n - node[i]*node[i])) return true; } else return false; } return true; } int main(){ int n; for(int n =1; n<= 60000; n ++ ){ BackTrack(0,n); BackTrack1(0,n); if(minnum != minnum1){cout<<n<<" error"<<endl;break;} } return 0; }