[BZOJ3733]Iloczyn(搜索)
玄学分数算法:贪心:每次尽量选取素因子个数少的数,用bfs实现,但是WA82(好像挺高的)。
刚开始以为是细节出错,所以...
对拍了100000组极限数据也没错
最后在skyh的提示下用小素数相乘来造数据对拍出了一组样例如下:
1
164025000 10
经过手模后发现我的算法会提前用掉以后非常关键的2导致后面的数无法区分。
100分做法:
搜索,但需要强大的剪枝:
设f[x][y]为从x位向后选y个约数的最小乘积,在搜索过程中判断当前剩下的数小于f则return false。
之后就可以得到WA82的好成绩...
我们通过一些小数据可以发现:f的增长是急速的,很可能爆int导致答案不准,
因为我们并不需要f的准确值,所以在处理f数组时把f与n取min即可。
+67...又一次创了我的历史新高...
这道题从开始思考到AC竟然用了4天?!
1 #include<bits/stdc++.h> 2 #define AA puts("ALITA") 3 #define DD puts("DYBALA") 4 using namespace std; 5 const int N=1e5+10; 6 int cnt,ans,n,k,T,p[N],f[N][25]; 7 int read() 8 { 9 register int sum,k=1;register char s; 10 while(s=getchar(),s<'0'||s>'9') if(s=='-') k=-1;sum=s-'0'; 11 while(s=getchar(),s>='0'&&s<='9') sum=sum*10+s-'0'; 12 return k*sum; 13 } 14 bool dfs(int x,int y,int z) 15 { 16 if(!y) return true; 17 if(x<p[z]||y>cnt-z+1||f[z][y]>x) return false; 18 if(x%p[z]==0&&dfs(x/p[z],y-1,z+1)) return true; 19 if(dfs(x,y,z+1)) return true; 20 return false; 21 } 22 void init(int x) 23 { 24 cnt=0; 25 for(int i=1;i<=sqrt(x);i++) 26 { 27 if(x%i) continue; 28 p[++cnt]=i; 29 if(i*i!=x) p[++cnt]=x/i; 30 } 31 sort(p+1,p+cnt+1); 32 f[cnt+1][0]=1; 33 for(int i=cnt;i>=1;i--) 34 { 35 f[i][0]=1; 36 for(int j=1;j<=min(k,cnt-i+1);j++) 37 { 38 f[i][j]=min(n,f[i+1][j-1]*p[i]); 39 } 40 } 41 } 42 bool work() 43 { 44 n=read();k=read(); 45 init(n); 46 return dfs(n,k,1); 47 } 48 signed main() 49 { 50 //freopen("1.in","r",stdin); 51 //freopen("1.out","w",stdout); 52 T=read(); 53 while(T--) 54 { 55 if(work()) puts("TAK"); 56 else puts("NIE"); 57 } 58 return 0; 59 }