玲珑OJ-Niro has a bicycle(DP)

来源:互联网 发布:gps数据统计分析 编辑:程序博客网 时间:2024/05/29 23:24



问题:http://www.ifrog.cc/acm/problem/1108


  题解:

设(F[i][j])表示已经考虑前(i)种药,并且前 ii 种药的(ix=1gcd(Ax,Ux)=j)(∑x=1igcd(Ax,Ux)=j) 的不同的, .U1...iU1...i.的种数。

转移显然是(F[i][j]=Wiu=1F[i1][jgcd(u,Ai)])(F[i][j]=∑u=1WiF[i−1][j−gcd(u,Ai)]),然而这不够优。

对于每一对((Ai,Wi))((Ai,Wi)),预处理出对于所有可能的UiUi,所有可能出现的(gcd)的值以及各个值对应的(Ui)(Ui)个数,

然后再开始在背包上转移,整道题的时间复杂度是(O(i=1Nd2(Ai)+Gi=1Nd(Ai)))(O(∑i=1Nd2(Ai)+G∗∑i=1Nd(Ai)))


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;typedef long long ll;#define Mod 1234321237#define maxn 1005int a[maxn],b[maxn];ll dp[maxn][maxn];int c[maxn][maxn];int gcd(int x,int y){if(y==0)return x;return gcd(y,x%y);}int  main(){int i,j,k,tmp,n,g;scanf("%d%d",&n,&g);for(i=1;i<=n;i++)scanf("%d",&a[i]);for(i=1;i<=n;i++)scanf("%d",&b[i]);for(i=1;i<=n;i++)for(j=1;j<=b[i];j++){tmp=gcd(a[i],j);if(tmp<=g-n+1)c[i][tmp]++;}dp[0][0]=1;for(i=1;i<=n;i++)for(j=1;j<=g-n+1;j++){if(j>a[i] || j>b[i])break;if(c[i][j]==0)continue;for(k=j;k<=g;k++){dp[i][k]+=dp[i-1][k-j]*c[i][j];if(dp[i][k]>Mod)dp[i][k]%=Mod;}}printf("%lld\n",dp[n][g]);}


0 0
原创粉丝点击