动态规划二维

这是一个关于挖黄山的故事,每座黄金山都有固定需要的人手和固定的收成(不能只挖一点),在固定人数的情况下,怎样挖才能挖最多(和小偷背包装东西一样的)

class GoldM {
    public int Gold;
    public int People;

    public GoldM(int gold, int people) {
        Gold = gold;
        People = people;
    }
}

class Program
{

    static void Main(string[] args)
    {
            //五座大金山等着你
        GoldM[] goldms = new GoldM[] {
            new GoldM(3000,5),
            new GoldM(5000,6),
            new GoldM(2000,2),
            new GoldM(6000,7),
            new GoldM(2000,3)
        };
        
        Console.WriteLine(GetMoreGold(5, 10, goldms));
        Console.ReadKey();
    }

    static int GetMoreGold(int n, int w, GoldM[] goldm) {

        int[] preResult = new int[w+1];
        int[] result = new int[w+1];

        //初始化第一行(边界),i代表人数
        for (int i = 0; i <= w; i++) {
            if (i < goldm[0].People)
            {
                preResult[i] = 0;
            }
            else {
                preResult[i] = goldm[0].Gold;
            }
        }
        goldm[0].isVisited = true;
                
                //这里从1开始,因为初始化边界的时候0号金山已经被访问过了
        for (int gg = 1; gg < n; gg++) {//金矿

            for (int pp = 0; pp <= w; pp++) {//人数
                if (pp < goldm[gg].People)
                {
                    result[pp] = preResult[pp];
                }
                else {
                        //状态转移方法
                    int newGold = preResult[pp - goldm[gg].People] + goldm[gg].Gold;
                    result[pp] = Math.Max(newGold, preResult[pp]);
                }
            }
            result.CopyTo(preResult,0);//复制数组
        }

        return result[w];
    }
}


二维的动态规划,思想其实还是一样的。先划分问题,一座金山,1-n个人分别来挖的最多产量;两座金山,1-n个人分别来挖的最多产量;三座金山,1-n个人分别来挖的最多产量等。其中两座金山时,只需要关注第二座金山就可,关于第一座金山的最优解已经从第一个问题中解答出来了。同样的,第三座金山的时候,也只需要关注第三座金山(挖还是不挖),然后从第二个问题中得到前两座金山的最优解。


首页 我的博客
粤ICP备17103704号