您的位置:首页 > 其它

2013 ACM/ICPC Asia Regional Changsha Online - G(DP)

2013-09-23 14:42 483 查看
第一眼就想到DP,然后想了N久就想不到可以不重算的DP 最后没办法了 先算出来 再去重。。

因为最多只有三个 对于三个来说有三种组合情况 x+y+z, x*y*z, x*y+z 那要么 x,y,z都不同 要么 有两个相同 要么有三个相同 对都不同情况我的DP结果会重复两次 对于有两个相同的会重复一次 统计出都相同的 两个相同的 最后减掉。。有点乱 不过A了

先预处理 时间差不多4S多 再O(1)询问

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define LL long long
#define mod 1000000007
int dp[4][4][80001],prim[80001],o[80001];
int p1[5][80001],p2[5][80001],p3[5][80001];
int num;
void init()
{
int i,j;
o[0] = 1;
o[1] = 1;
for(i = 2; i <= 80000; i ++)
{
if(!o[i])
{
for(j = i+i; j <= 80000; j += i)
{
o[j] = 1;
}
}
}
num = 1;
for(i = 2; i <= 80000; i ++)
{
if(!o[i])
prim[num++] = i;
}
for(i = 1; i < num ; i++)
{
dp[1][1][prim[i]] = 1;
dp[2][1][prim[i]] = 1;
dp[3][1][prim[i]] = 1;
}
for(i = 1; i < num ; i++)
{
for(j = prim[i] ; j <= 80000 ; j++)
{
int k = j-prim[i];
if(!o[k]&&k>=prim[i])
dp[1][2][j] = (dp[1][2][j]+dp[1][1][k])%mod;
if(j%prim[i]==0)
{
int k = j/prim[i];
if(k>=prim[i])
{
dp[2][2][j] = (dp[2][2][j]+dp[2][1][k])%mod;
dp[3][2][j] = dp[2][2][j];
}
}
}
}
for(i = 1; i < num ; i++)
{
for(j = prim[i] ; j <= 80000 ; j++)
{
if(j%prim[i]==0)
dp[2][3][j] = (dp[2][3][j]+dp[2][2][j/prim[i]])%mod;
dp[3][3][j] = (dp[3][2][j-prim[i]]+dp[3][3][j])%mod;
dp[1][3][j] = (dp[1][3][j]+dp[1][2][j-prim[i]])%mod;
}
}
for(i = 1; i < num ; i++)
{
LL s = (LL)prim[i]*(LL)prim[i]*(LL)prim[i];
LL ss = prim[i]*3;
if(ss<=80000)
p2[1][ss] = (p2[1][ss]+1)%mod;
if(s<=80000)
p1[1][s] = (p1[1][s]+1)%mod;
for(j = 1 ; j < num ; j++)
{
if(j==i)
continue;
LL s = (LL)prim[i]*(LL)prim[i]*(LL)prim[j];
if(s<=80000)
p1[2][s] = (p1[2][s]+1)%mod;
else
break;
}
for(j = 1 ; j < num ; j++)
{
if(j==i)
continue;
LL ss = (LL)prim[i]*2+prim[j];
if(ss<=80000)
p2[2][ss] = (p2[2][ss]+1)%mod;
else
break;
}
}
}
int main()
{
int x;
init();
while(scanf("%d",&x)!=EOF)
{
LL s = (dp[1][1][x]+dp[1][2][x]+dp[2][2][x]+dp[3][3][x])%mod;
s = (s+(dp[2][3][x]-(p1[1][x]+p1[2][x]*2))/3+p1[1][x]+p1[2][x])%mod;
s = (s+(dp[1][3][x]-(p2[1][x]+p2[2][x]*2))/3+p2[1][x]+p2[2][x])%mod;
if(s<0)
s+=mod;
printf("%lld\n",s);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: