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 }
View Code

 

 

 

你可能感兴趣的:(online)