zoukankan      html  css  js  c++  java
  • zoj 3662 Math Magic(DP)

    挺水的dp,脑抽把mod多打了个0结果弹了2次。

    好吧,我们记录dp[i][j][k]为选i个数字,和为j,lcm为k的个数有多少种

    接下来枚举第i+1个数字进行转移就行了,开三维会MLE,可以用滚动数组做。

    我的做法有点类似背包,将lcm和sum从大到小枚举,这样避免重复。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #define mod 1000000007
     5 using namespace std;
     6 int dp[1010][40];
     7 int f[1010][1010];
     8 int n,m,k;
     9 int a[1010],aa[1010];
    10 int gcd(int a,int b){
    11     if(f[a][b]!=-1) return f[a][b];
    12     if(b) return f[a][b]=gcd(b,a%b);
    13     else return f[a][b]=a;
    14 }
    15 int lcm(int a,int b){
    16     return a/gcd(a,b)*b;
    17 }
    18 
    19 int main(){
    20     memset(f,-1,sizeof f);
    21     while(~scanf("%d%d%d",&n,&m,&k)){
    22         memset(dp,0,sizeof dp);
    23         int ct=0;
    24         for(int i=1;i<=m;i++){
    25            if(m%i==0) a[ct++]=i;
    26         }
    27         for(int i=0;i<ct;i++) aa[a[i]]=i;
    28         int cur=0;
    29         for(int i=0;i<ct;i++) dp[a[i]][i]=1;
    30         for(int i=2;i<=k;i++,cur=1-cur){
    31             for(int j=ct-1;j>=0;j--){//i-1 lcm
    32                for(int p=n;p>=0;p--){//i-1 sum
    33                   if(!dp[p][j]) continue;
    34                   for(int q=0;q<ct&&a[q]+p<=n;q++){
    35                       int x=lcm(a[j],a[q]);
    36                       //cout<<p<<" "<<a[j]<<" "<<a[q]<<endl;
    37                       dp[p+a[q]][aa[x]]=(dp[p+a[q]][aa[x]]+dp[p][j])%mod;
    38                   }
    39                   dp[p][j]=0;
    40                }
    41             }
    42         }
    43         printf("%d
    ",dp[n][ct-1]);
    44     }
    45     return 0;
    46 }
    zoj3662
  • 相关阅读:
    微信支付
    JVM调优的正确姿势
    JVM常用调优案例
    JVM调优实践
    jvm优化必知系列——监控工具
    JVM 调优案例分析1
    一次生产的JVM优化
    记录一次JVM配置优化的案例
    JVM之内存和对象创建过程
    Java类加载过程
  • 原文地址:https://www.cnblogs.com/wonderzy/p/3412604.html
Copyright © 2011-2022 走看看