zoukankan      html  css  js  c++  java
  • hdu 4427 DP

    题意:

    给你k个数的和和k个数的最小公倍数。问你一共有多少满足条件的解。

    用三维来表示状态。

    dp[i][j][k]。表示长度为i。和为j。最小公倍数为k的方法数。

    设a为解的第i+1个数。

    那么状态转移就为

    dp[i+1][j+a][lcm(a,k)]+=dp[i][j][k]。

    lcm为最大公倍数。

    由于三维开不下就只能用滚动数组了。

    为了节约时间先预处理出1000以内任意两数的最小公倍数。注意一点。一个数学常识。如果这k个数的最小公倍数是

    x。那么这k个数肯定都是x的因子。所以先预处理出x的因子。这样就可以有效的减少枚举范围。还有memset要慎用尤其是在这种数量级下。

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cmath>
     5 #include <memory.h>
     6 using namespace std;
     7 typedef long long ll;
     8 const int mod = 1e9 + 7;
     9 const ll maxn = 1e5 + 10;
    10 int dp[2][1005][1005],fac[1005],cnt,lcm[1005][1005];
    11 int gcd(int a,int b){
    12     return b == 0?a:gcd(b,a%b);
    13 }
    14 void init(){
    15     for(int i = 1;i <= 1000;i++)
    16         for(int j = i;j <= 1000;j++)
    17             lcm[i][j] = lcm[j][i] = i*j/gcd(i,j);
    18 }
    19 int n,m,k;
    20 int main() {
    21     //freopen("in.txt","r",stdin);
    22     init();
    23     while(~scanf("%d%d%d",&n,&m,&k)){
    24         memset(dp,0,sizeof(dp));
    25         memset(fac,0,sizeof(fac));
    26         cnt = 0;
    27         for(int i = 1;i <= m;i++)
    28             if(m % i == 0) fac[++cnt] = i;
    29         int id = 0;
    30         for(int i = 1;i <= cnt;i++)
    31             dp[id][fac[i]][fac[i]] = 1;
    32         for(int i = 1;i <= k - 1;i++){
    33             for(int t1 = 1;t1 <= n;t1++)
    34                 for(int t2 = 1;t2 <= cnt;t2++)
    35                     dp[id^1][t1][fac[t2]] = 0;
    36             for(int j = 1;j <= n;j++){
    37                 for(int t = 1;t <= cnt;t++){
    38                     if(!dp[id][j][fac[t]]) continue;
    39                     for(int x = 1;x <= cnt;x++){
    40                         if(j + fac[x] > n) break;
    41                         dp[id^1][j+fac[x]][lcm[fac[t]][fac[x]]] += dp[id][j][fac[t]];
    42                         dp[id^1][j+fac[x]][lcm[fac[t]][fac[x]]] %= mod;
    43                     }
    44 
    45                 }
    46 
    47         }
    48             id ^= 1;
    49         }
    50     printf("%d
    ",dp[id][n][m]);
    51     }
    52 
    53 
    54     return 0;
    55 }
  • 相关阅读:
    【JavaScript】explode动画
    【JavaScript】插件参数的写法
    【webpack】理解配置文件
    你真的了解盒模型么
    一看看懂Protocol Buffer(协议篇)
    es7你都懂了吗?今天带你了解es7的神器decorator
    快速了解react
    简单聊一聊那些svg的沿路径运动
    转转RN工程化历程
    微信小程序内嵌网页的一些(最佳)实践
  • 原文地址:https://www.cnblogs.com/shimu/p/5961885.html
Copyright © 2011-2022 走看看