hdu 5656 CA Loves GCD(dp)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5656 CA Loves GCD(dp)相关的知识,希望对你有一定的参考价值。
题意:
T组数据:
n个数字,任取1-n个数字中所有组合的GCD的和
思路:dp
/*
dp[i][j] 表示用前i个数字gcd=j的所有方法数。
dp[i + 1][gcd(j,a[i + 1])] += dp[i][j];
dp[i + 1][j] += dp[i][j];
*/
1 #include<cstdio> 2 #include<cstring> 3 #include<cstring> 4 5 #include<algorithm> 6 #include<set> 7 #include<map> 8 #include<vector> 9 #include<stack> 10 #include<string> 11 #include<cmath> 12 13 #include<iostream> 14 #define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i)) 15 #define all(o) (o).begin(), (o).end() 16 #define mem(o) memset((o),0,sizeof((o))); 17 #define memL(o) memset((o),0x7f7f7f7f,sizeof((o))); 18 using namespace std; 19 typedef long long ll; 20 const double PI = acos(-1.0); 21 const int MOD = 100000007; 22 23 int GCD[1005][1005]; 24 int a[1005]; 25 ll dp[1005][1005]; 26 int gcd(int aa,int bb){ 27 return bb == 0 ? aa : gcd(bb,aa%bb); 28 } 29 void init(){ 30 rep(i,1002){ 31 rep(j,1002){ 32 GCD[i][j] = gcd(i,j); 33 } 34 } 35 36 } 37 /* 38 dp[i][j] 表示用前i个数字gcd=j的所有方法数。 39 40 dp[i + 1][gcd(j,a[i + 1])] += dp[i][j]; 41 dp[i + 1][j] += dp[i][j]; 42 */ 43 int main(){ 44 45 int T,n; 46 init(); 47 scanf("%d",&T); 48 while(T--){ 49 scanf("%d",&n); 50 int maxA = 0; 51 rep(i,n){ 52 scanf("%d",&a[i]); 53 maxA = max(a[i],maxA); 54 } 55 mem(dp); 56 dp[0][0] = 1; 57 rep(i,n){ 58 rep(j,(maxA+1)){ 59 dp[i+1][j] = (dp[i+1][j] + dp[i][j])%MOD; 60 dp[i+1][ GCD[a[i]][j] ] = (dp[i][j] + dp[i+1][ GCD[a[i]][j] ])%MOD; 61 } 62 } 63 ll res = 0; 64 for(int i = 0 ; i <= 1002 ; i ++){ 65 res = (res + (dp[n][i]*i)%MOD)%MOD; 66 } 67 printf("%lld\n",res); 68 } 69 70 71 return 0; 72 }
以上是关于hdu 5656 CA Loves GCD(dp)的主要内容,如果未能解决你的问题,请参考以下文章
数学(GCD,计数原理)HDU 5656 CA Loves GCD