码迷,mamicode.com
首页 > 其他好文 > 详细

多重部分和问题

时间:2014-09-01 21:02:53      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:使用   for   问题   时间   c   算法   c++   as   dp   

描述:

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

多重部分和问题

标签:使用   for   问题   时间   c   算法   c++   as   dp   

原文地址:http://www.cnblogs.com/dandi/p/3949929.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!