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

 

posted @ 2019-08-16 21:21  ATHOSD  阅读(97)  评论(0编辑  收藏  举报