1. 程式人生 > >bzoj:1053 [POI2002][HAOI2007]反素數

bzoj:1053 [POI2002][HAOI2007]反素數

這題的本質就是求約數最多的數最小是多少。

就直接列舉每個質數的指數就行了

然後前10個質數的乘積是大於2*10^9,然後加兩個約束就行了

約束

1、第i+1個質數的指數一定不會比第i個質數的指數的大

2、只用列舉10個質數

程式碼:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int prime[15] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31}, a[15];
int n, anss;
ll ans;
//p  :當前是第幾個質數
//pr : 當前質數的指數
//sum :當前所有數的乘積和
//ysh :當前所有數的約束和
//limit:上一個質數的指數(約束1)
void dfs(int p, int pr, ll sum, int ysh, int limit){
	if(pr > limit) return;//約束1
	if(anss < ysh || anss == ysh && ans > sum){//按題目要求更新答案
		ans = sum;
		anss = ysh;
	}
	if(p > 10) return;//約束2
	if(sum * prime[p] <= n) dfs(p, pr + 1, sum * prime[p], ysh + a[p - 1], limit); //當前質數的指數加1,學過一點點奧數的都知道ysh是如何更新的
	a[p] = ysh;
	dfs(p + 1, 0, sum, ysh, pr);//到下一個質數
}
int main(){
	a[0] = 1;
	scanf("%d", &n);
	dfs(1, 0, 1, 1, (1<<30));
	printf("%lld", ans);//輸出
	return 0;
}//(^_^)

還是挺簡單的嘛……