2013 ACM/ICPC Asia Regional Changsha Online - G(DP)
第一眼就想到DP,然后想了N久就想不到可以不重算的DP 最后没办法了 先算出来 再去重。。
因为最多只有三个 对于三个来说有三种组合情况 x+y+z, x*y*z, x*y+z 那要么 x,y,z都不同 要么 有两个相同 要么有三个相同 对都不同情况我的DP结果会重复两次 对于有两个相同的会重复一次 统计出都相同的 两个相同的 最后减掉。。有点乱 不过A了
先预处理 时间差不多4S多 再O(1)询问
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 using namespace std; 7 #define LL long long 8 #define mod 1000000007 9 int dp[4][4][80001],prim[80001],o[80001]; 10 int p1[5][80001],p2[5][80001],p3[5][80001]; 11 int num; 12 void init() 13 { 14 int i,j; 15 o[0] = 1; 16 o[1] = 1; 17 for(i = 2; i <= 80000; i ++) 18 { 19 if(!o[i]) 20 { 21 for(j = i+i; j <= 80000; j += i) 22 { 23 o[j] = 1; 24 } 25 } 26 } 27 num = 1; 28 for(i = 2; i <= 80000; i ++) 29 { 30 if(!o[i]) 31 prim[num++] = i; 32 } 33 for(i = 1; i < num ; i++) 34 { 35 dp[1][1][prim[i]] = 1; 36 dp[2][1][prim[i]] = 1; 37 dp[3][1][prim[i]] = 1; 38 } 39 for(i = 1; i < num ; i++) 40 { 41 for(j = prim[i] ; j <= 80000 ; j++) 42 { 43 int k = j-prim[i]; 44 if(!o[k]&&k>=prim[i]) 45 dp[1][2][j] = (dp[1][2][j]+dp[1][1][k])%mod; 46 if(j%prim[i]==0) 47 { 48 int k = j/prim[i]; 49 if(k>=prim[i]) 50 { 51 dp[2][2][j] = (dp[2][2][j]+dp[2][1][k])%mod; 52 dp[3][2][j] = dp[2][2][j]; 53 } 54 } 55 } 56 } 57 for(i = 1; i < num ; i++) 58 { 59 for(j = prim[i] ; j <= 80000 ; j++) 60 { 61 if(j%prim[i]==0) 62 dp[2][3][j] = (dp[2][3][j]+dp[2][2][j/prim[i]])%mod; 63 dp[3][3][j] = (dp[3][2][j-prim[i]]+dp[3][3][j])%mod; 64 dp[1][3][j] = (dp[1][3][j]+dp[1][2][j-prim[i]])%mod; 65 } 66 } 67 for(i = 1; i < num ; i++) 68 { 69 LL s = (LL)prim[i]*(LL)prim[i]*(LL)prim[i]; 70 LL ss = prim[i]*3; 71 if(ss<=80000) 72 p2[1][ss] = (p2[1][ss]+1)%mod; 73 if(s<=80000) 74 p1[1][s] = (p1[1][s]+1)%mod; 75 for(j = 1 ; j < num ; j++) 76 { 77 if(j==i) 78 continue; 79 LL s = (LL)prim[i]*(LL)prim[i]*(LL)prim[j]; 80 if(s<=80000) 81 p1[2][s] = (p1[2][s]+1)%mod; 82 else 83 break; 84 } 85 for(j = 1 ; j < num ; j++) 86 { 87 if(j==i) 88 continue; 89 LL ss = (LL)prim[i]*2+prim[j]; 90 if(ss<=80000) 91 p2[2][ss] = (p2[2][ss]+1)%mod; 92 else 93 break; 94 } 95 } 96 } 97 int main() 98 { 99 int x; 100 init(); 101 while(scanf("%d",&x)!=EOF) 102 { 103 LL s = (dp[1][1][x]+dp[1][2][x]+dp[2][2][x]+dp[3][3][x])%mod; 104 s = (s+(dp[2][3][x]-(p1[1][x]+p1[2][x]*2))/3+p1[1][x]+p1[2][x])%mod; 105 s = (s+(dp[1][3][x]-(p2[1][x]+p2[2][x]*2))/3+p2[1][x]+p2[2][x])%mod; 106 if(s<0) 107 s+=mod; 108 printf("%lld\n",s); 109 } 110 return 0; 111 }