如何改进此动态编程解决方案(算法优化)

时间:2015-07-09 17:57:51

标签: algorithm language-agnostic dynamic-programming

问题陈述:

移动保证公司(ACM)是一家为人们提供物品的公司。最近,一些学校希望将他们的计算机转移到另一个地方。所以他们要求ACM帮助他们。一所学校保留K卡车用于移动,它有N台计算机可以移动。为了不浪费卡车,学校要求ACM使用所有卡车。也就是说,每辆卡车上必须有一些电脑,而且没有空卡车。 ACM想知道K卡车移动N台计算机时存在多少分区密码,ACM要求您计算给定N和K的不同密码的数量。您无需关心订单。例如,N = 7,K = 3,以下3个分区实例被认为是同一个,应该算作一个sheme:" 1 1 5"," 1 5 1&#34 ;," 5 1 1"。每辆卡车都可以携带几乎无限的电脑!!

节省时间

您必须计算[1..k]存在多少个序列,以便:

1)a [i] + a [2] + .... + a [k] = N使得排列无关紧要

我的O(N * K ^ 2)解决方案(无法弄清楚如何改进它)

#include<assert.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int DP[5001][5001];
void ini()
{
    int i,j,k;
    DP[0][0]=1;
    for(k=1;k<=500;k++)
        for(j=1;j<=500;j++)
           for(i=1;i<=500;i++)
            {
                DP[i][j]+=j>=k?DP[i-1][j-k]:0;
                DP[i][j]%=1988;
            }
    return ;
}
int main()
{
    ini();
    int N,K,i,j;
    while(1)
    {
        scanf("%d%d",&N,&K);
        if(N==0 && K==0)
            return 0;
        int i;
        if(DP[K][N]==0)
        {assert(0);}
        printf("%d\n",DP[K][N]);
    }
    return 0;
}

我的解决方案说明DP [i] [j]表示我只能使用i Trucks的总计j计算机的数量。 k表示我正在处理的计算机数量,这意味着我只是避免排列!

如何将其提高到O(N * K)?

问题约束

  

N(1 <= N <= 5000)且K(1 <= K <= N)

问题链接:Problem Spoj

2 个答案:

答案 0 :(得分:3)

只要说你有K礼盒和N个巧克力。

我将从递归开始,很容易将其转换为迭代解决方案。

避免重复的关键是按升序分配巧克力(降序也有效)。所以你给了7个巧克力,我在第一个盒子里放了2个巧克力,我会在第二个盒子里放至少2。为什么?这有助于避免重复。

         now onwards TCL = totalChocholatesLeft & TBL  = totalBinsLeft

         So S(TCL,TBL) =  S(TCL-TBL,TBL) + S(TCL,TBL-1);

         you have to call the above expression starting with S(n-k), k)

         Why? because all boxes need at least one item so first put `1` each box. 
         Now you are left with only `n-k` chocolates.

这就是全部!那就是DP递归。

它是如何工作的?

        So in order to remove repetitions we are maintaning the ascending order.
        What is the easiest way to maintain the ascending order ? 

如果你在第i个盒子中放入1个巧克力,请在其前面的所有方框中放置1个i+1, i++2 .....k。 因此,在将巧克力放入礼品盒后,您有两种选择:

要么继续使用当前框:

                S(TCL-TBL,TBL) covers this

或移动下一个框只是再也不考虑这个框

                S(TCL,TBL-1) covers this.

等效DP会产生TC:O(NK)

答案 1 :(得分:2)

此问题相当于在n-k个相同的单元格中放置k个相同的球(在已经在每个单元格中放置一个球以确保它不为空)。

这可以使用递推公式解决:

D(n,0) = 0       n > 0
D(n,k) = 0       n < 0
D(n,1) = 1       n >= 0
D(n,k) = D(n,k-1) + D(n-k,k)

说明:

停止条款:

  • D(n,0) - 无法在0个单元格中放入n> 0个球
  • D(n <0,k) - 无法将负数的球放入k个单元中
  • D(n,1) - 将n个球放入1个单元格的一种方法:全部在此单元格中

<强>复发:

我们有两个选择。

  1. 我们要么有一个(或更多)空单元格,所以我们会解决同样的问题,并减少一个单元格:D(n,k-1)
  2. 否则,我们没有空单元格,所以我们在每个单元格中放置一个球,使用相同数量的单元格和更少的球进行递归,D(n-k,k)
  3. 这两种可能性是不相交的集合,因此两个集合的联合是两个大小的总和,因此D(n,k) = D(n,k-1) + D(n-k,k)

    上述递归公式很容易在O(1)(假设O(1)算术)中计算,如果&#34;更低&#34;问题已知,DP解决方案需要填写大小为(n+1)*(k+1)的表格,因此此解决方案为O(nk)