http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3681
题目意思稍微有些抽象,不好叙述。这里直接讲方法
首先O(sqrt(n))预处理出n的所有约数。
对于一个数k,至多需要(k+1)/2个人
而对于k的每一个约数a(a>1),则需要ans[a] * ans[k/a]人,当然取一个最小值。
按n的约数从小到大DP即可,。
代码如下:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<map> 6 using namespace std; 7 int l,a[20010]; 8 map<int,int> mp; 9 int main() 10 { 11 int n,m; 12 while (~scanf("%d%d",&n,&m)) 13 { 14 if(n==1){ 15 puts(m?"Yes":"No"); 16 puts("1"); 17 continue; 18 } 19 int ans=n; 20 l=0; 21 for(int i=1;i*i<=n;i++)if(n%i==0){ 22 a[l++]=i; 23 if(n/i!=i)a[l++]=n/i; 24 } 25 sort(a,a+l); 26 mp.clear(); 27 for(int i=1;i<l;i++){ 28 int tmp=a[i]/2+1; 29 for(int j=1;j<i;j++)if(a[i]%a[j]==0){ 30 int tmp2=mp[a[j]]*mp[a[i]/a[j]]; 31 if(tmp2<tmp) 32 tmp=tmp2; 33 } 34 mp[a[i]]=tmp; 35 } 36 ans=mp[n]; 37 puts(ans<=m?"Yes":"No"); 38 printf("%d\n",ans); 39 } 40 return 0; 41 }