hdu3463(DP)

来源:互联网 发布:基三成女捏脸数据 编辑:程序博客网 时间:2024/05/29 17:17

Goldbach Division

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 1189    Accepted Submission(s): 411


Problem Description
Everybody knows Goldbach Conjecture! Here is one edition of it:

1) Every odd integer greater than 17 can be written as three different odd primes’ sum;
2) Every even integer greater than 6 can be written as two different odd primes’ sum.

Loving the magical math conjecture very much, iSea try to have a closer look on it. Now he has a new definition: Goldbach Division. If we express an even integer as two different odd primes’ sum, or odd integer as three different odd primes’ sum, we call it a form of Goldbach Division of N, using a symbol G(N).

For example, if N = 18, there are two ways to divide N.
18 = 5 + 13 = 7 + 11
If N = 19, there is only one way to divide N.
19 = 3 + 5 + 11

Here comes your task, give a integer N, find |G(N)|, the number of different G(N).
 

Input
There are several test cases in the input.

Each test case includes one integer N (1 <= N <= 20000).

The input terminates by end of file marker.
 

Output
For each test case, output one integer, indicating |G(N)|.
 

Sample Input
1819
 

Sample Output
21
Hint
There may be 2000 cases, be careful.
 
本题首先必须直到20000以内奇素数,这点可以在O(n^1.5)时间复杂度内完成
其次要求偶数的两个不同加因子,奇数的三个不同加因子的个数
若直接枚举时间复杂度为O(n^3),暴力枚举法超时;可以考虑用动态规划的思想避免重复运算
 
#include<iostream>#include<cstdio>#include<cmath>using namespace std;const int MAX=20000+10;int ind;int Pri[MAX];int dp[MAX];//int hash[MAX];void Prime(){int i,j,tmp;ind=0;for(i=3;i<=20000;i+=2){tmp=(int)sqrt(i*1.0);for(j=2;j<=tmp;j++)if(i%j==0)break;if(j>tmp)Pri[ind++]=i;}}/*void DP()//利用hash直接枚举,超时的算法{int i,j,k;for(i=0;i<ind;i++){for(j=i+1;j<ind;j++){if(Pri[i]+Pri[j]>20000)break;hash[Pri[i]+Pri[j]]++;for(k=j+1;k<ind;k++){if(Pri[i]+Pri[j]+Pri[k]>20000)break;hash[Pri[i]+Pri[j]+Pri[k]]++;}}}}*/void DP(){    int i,j;for(i=0;i<ind;i++){for(j=0;Pri[i]+j<20000;j+=2)dp[Pri[i]+j]+=dp[j];for(j=0;j<i&&Pri[i]+Pri[j]<=20000;j++)dp[Pri[i]+Pri[j]]++;}}int main(){int n,i,j,k;Prime();memset(dp,0,sizeof(dp));//memset(hash,0,sizeof(hash));DP();/*for(i=0;i<ind;i++){cout<<Pri[i]<<" ";if(i%10==0)cout<<endl;}*///cout<<ind<<endl;while(~scanf("%d",&n)){printf("%d\n",dp[n]);}return 0;}

 
 
 
 
 
 
原创粉丝点击