nefu 394 素数价值(dp或规律)

来源:互联网 发布:anjular.js 编辑:程序博客网 时间:2024/04/30 20:13

素数价值

Time Limit 3000ms

Memory Limit 65536K

description

我们来定义下一个数的素数价值,假设这个数是N(2<=N<=50000),我们可以通过以下两种方法:1.把当前数字除以某个素数(当然得可以整除),即N = N / p;2.把当前数字减去某个素数(保证减后结果为正整数),即N = N - p;这个数字的素数价值是最少得通过多少次以上的方法使得它变成0.

input

第一行是测试数据的组数T,接着有T组测试数据.每组测试数据有两个数字a,b(2 <= a <= b <= 50000).

output

对于每组测试数据,输出区间[a,b]之间所有数字的素数价值的和.

sample_input

22 32 5

sample_output

25

hint

source

 

哥德巴赫猜想:任何大于偶数都等于两个素数和;

分类:1大于2的偶数,价值为2

          2:奇数:若是质数价值为1,若是等于两个质数之积价值是2,若是等于2加上某个质数价值等于2,其他价值等于3

 

#include<cstdio>#include<algorithm>#include<cstring>#define N 50003using namespace std;bool noprime[N];int prime[N];int num;int f[N];void pprim(){  memset(noprime,0,sizeof(noprime));  noprime[0]=1;noprime[1]=1;  num=0;  memset(f,0,sizeof(f));  f[2]=1;  for(int i=2;i<N-2;i++)  {    if(!noprime[i])    {      prime[num++]=i;      f[i]=1;//质数      f[i+2]=2;//质数+2      for(int j=i+i;j<N;j+=i)      {        noprime[j]=1;      }    }  }  int z;  for(int i=0;i<num;i++)  for(int j=0;j<num;j++)  {    z=prime[i]*prime[j];    if(z<N)    f[z]=2;    else break;  }  for(int i=4;i<N;i+=2)//偶数  f[i]=2;  for(int i=3;i<N;i+=2)//其他类  if(f[i]==0)f[i]=3;}int main(){  int a,b;  pprim();  int cas;  scanf("%d",&cas);  //while(scanf("%d",&cas)!=EOF) // { // freopen("1.txt","w",stdout);    while(cas--)    {      scanf("%d%d",&a,&b);      int sum=0;    for(int i=a;i<=b;i++)    sum+=f[i];    //for(int i=2;i<N;i++)    //printf("%d %d\n",i,f[i]);    printf("%d\n",sum);    } // }}


 

 

 

先预处理DP
dp[i + prime[j]] = minx(dp[i + prime[j]], dp[i] + 1);

dp[i * prime[j]] = minx(dp[i * prime[j]], dp[i] + 1);
然后统计.

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;const int MAXP = 50100;const int N = 50000;int prime[MAXP] = {0},num_prime = 0;int isNotPrime[MAXP] = {1, 1};void prime_select(){int i;for(int i = 2 ; i <  MAXP ; i ++){if(! isNotPrime[i])prime[num_prime ++]=i;for(int j = 0 ; j < num_prime && i * prime[j] <  MAXP ; j ++){isNotPrime[i * prime[j]] = 1;if( !(i % prime[j]))break;}}}int dp[MAXP];inline int minx(const int &a, const int &b){return a > b ? b : a;}void doDp(){memset(dp, -1, sizeof(dp));int i, j, k;dp[0] = 0;for (i = 0; i <= N; i ++){if(i == 1)continue;for (j = 0; j < num_prime && i + prime[j] <= N; j ++){if(dp[i + prime[j]] == -1)dp[i + prime[j]] = dp[i] + 1;dp[i + prime[j]] = minx(dp[i + prime[j]], dp[i] + 1);}if(i != 0)for (j = 0; j < num_prime && i * prime[j] <= N; j ++){//isPrimeif(dp[i * prime[j]] == -1)dp[i * prime[j]] = dp[i] + 1;dp[i * prime[j]] = minx(dp[i * prime[j]], dp[i] + 1);}}return ;}int main(){  //freopen("2.out","w",stdout);prime_select();doDp();int n, a, b;int i;int t;scanf("%d", &t);while (t --){scanf("%d %d", &a, &b) ;int ans = 0;//for(int i=2;i<N;i++)//printf("%d %d\n",i,dp[i]);for (i = a; i <= b; i++)ans += dp[i];printf("%d\n", ans);}return 0;}


 

 

 

 

 

 

 

 

 
	
				
		
原创粉丝点击