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

  • 相关阅读:
    linux:centOs7换源阿里云
    nginx:负载均衡实战(一)
    linux-安装jdk以及tomcat
    nginx:在linux上进行nginx的安装
    开源 免费 java CMS
    使用PHP获取汉字的拼音(全部与首字母)
    php版获取重定向后地址的代码分享
    php获取数组中重复数据的两种方法
    php删除html标签的三种解决方法
    php curl 伪造IP来源的代码分享
  • 原文地址:https://www.cnblogs.com/dandi/p/3949929.html
Copyright © 2011-2022 走看看