zoukankan      html  css  js  c++  java
  • 多重部分和问题

    描述:

      N种不同数字ai每种mi个,判断是否可以选择若干个使得和为K
      N<=100,k<=100000,ai,mi<=100000,均大于零。

    分析:

      裸算法:

        DP[I][K]=0..1——前i个物品是否可以组成K

        for (int i=1;i<=n;i++)
        for (int k=0;k<=K;k++)
          if (Dp[i-1][k])
            for (int c=0;c<=mi;c++)
              Dp[i][k+c*ai]=1;

        时间复杂度显然是n*k*mi sum i=1..n 十分巨大

        因为如果使用DP求BOOL往往很浪费,放弃了许多可以利用的信息。

        如果我们不仅仅求出能否得到目标,并且记录下来剩下来多少个,可以减小很大的复杂度。

        改为DP[I][K]为前I组成K,第I可以剩下最多为多少。

          for (int i=1;i<=n;i++)
          for (int k=0;k<=K;k++)
            if (k>=ai)
            {
              if (Dp[i-1][k])
              {
                //上一个已经可以构成
                Dp[i][k]=mi;
              }

              if (Dp[i][k-ai])
              {
                //如果DP[I][K]可以构成,那么DP[I][K-AI]是必然可以构成的
                Dp[i][k]=Dp[i][k-ai]-1;
              }
            }
            else
            {
              Dp[i][k]=-1;
            }

  • 相关阅读:
    20165214 第八周学习任务
    20165214 实验二 Java面向对象程序设计
    20165214 结队编程项目-四则运算
    20165214 第七周学习任务
    20165214 第六周学习任务
    20165214 实验一 Java开发环境的熟悉
    20165313 《Java程序设计》第八周学习总结
    结对编程-四则运算
    2017-2018-2 20165313实验二《Java面向对象程序设计》
    20165313 《Java程序设计》第七周学习总结
  • 原文地址:https://www.cnblogs.com/dandi/p/3949929.html
Copyright © 2011-2022 走看看