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;
            }

  • 相关阅读:
    Visual studio 2008中添加manifest文件
    SqlServer2008R2安装
    今天在Google上搜我的名字,具然埔客园排在第一位。
    今天又到此一游,原因,是为了寻找传说中的Team foundation server,很难找呀,这个东东。
    硬件基础知识
    循环冗余检验应用
    【转】网络变压器的作用
    PADS无模命令总结
    单片机后缀说明
    QuartusII之Warning警告分析
  • 原文地址:https://www.cnblogs.com/dandi/p/3949929.html
Copyright © 2011-2022 走看看