購物單

 

王強今天很開心,公司發給N元的年終獎。王強決定把年終獎用於購物,他把想買的物品分爲兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:

 

主件 附件
電腦 打印機,掃描儀
書櫃 圖書
書桌 檯燈,文具
工做椅

 

若是要買歸類爲附件的物品,必須先買該附件所屬的主件。每一個主件能夠有 0 個、 1 個或 2 個附件。附件再也不有從屬於本身的附件。王強想買的東西不少,爲了避免超出預算,他把每件物品規定了一個重要度,分爲 5 等:用整數 1  5 表示,第 5 等最重要。他還從因特網上查到了每件物品的價格(都是 10 元的整數倍)。他但願在不超過 N 元(能夠等於 N 元)的前提下,使每件物品的價格與重要度的乘積的總和最大。
    設第 j 件物品的價格爲 v[j] ,重要度爲 w[j] ,共選中了 k 件物品,編號依次爲 j 1 , j 2 ,……, j k ,則所求的總和爲:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 爲乘號)
    請你幫助王強設計一個知足要求的購物單。

 

 

知識點 字符串
運行時間限制 0M
內存限制 0
輸入

輸入的第 1 行,爲兩個正整數,用一個空格隔開:N mios

(其中 N ( <32000 )表示總錢數, m ( <60 )爲但願購買物品的個數。)

 

從第 2 行到第 m+1 行,第 j 行給出了編號爲 j-1 的物品的基本數據,每行有 3 個非負整數 v p q

 

(其中 v 表示該物品的價格( v<10000 ), p 表示該物品的重要度( 1  5 ), q 表示該物品是主件仍是附件。若是 q=0 ,表示該物品爲主件,若是 q>0 ,表示該物品爲附件, q 是所屬主件的編號)

 

 

輸出
 輸出文件只有一個正整數,爲不超過總錢數的物品的價格與重要度乘積的總和的最大值( <200000 )。

 

 

樣例輸入 1000 5 800 2 0 400 5 1 300 5 1 400 3 0 500 2 0
樣例輸出 2200

#include<iostream>
using namespace std;

int max(int a, int b)
{
    return a>b?a:b;
}

int main()
{
    int N,m;
    cin>>N;
    cin>>m;

    int *arrv;
    int *arrw;
    int *arridx;
    int **arrsub;
    int *arrsubNum;

    arrv = new int [m+1];
    arrw = new int [m+1];
    arridx = new int [m+1];

    arrsub = new int* [m+1];
    for(int i=0; i<m+1; i++)
    {
        arrsub[i] = new int [2];
    }
    arrsubNum = new int [m+1];


    int minv = 100000;
    for(int i=1; i<=m; i++)
    {
        int tmpv, tmpw, tmpidx;
        cin>>tmpv>>tmpw>>tmpidx;

        if(tmpidx==0 && tmpv < minv)
        {
            minv = tmpv;
        }

        arrv[i] = tmpv/10;
        arrw[i] = tmpw;
        arridx[i] = tmpidx;
    }
    minv = minv/10;


    for(int i=1; i<=m; i++)
    {
        arrsubNum[i] = 0;
    }

    for(int i=1; i<=m; i++)
    {
        if(arridx[i]!=0)
        {
            int idx = arridx[i];
            arrsub[idx][ arrsubNum[idx] ] = i;
            arrsubNum[idx]++;
        }
    }
/*
    cout<<"ok imput"<<endl;
    for(int i=1; i<=m; i++)
    {
        cout<<arrv[i]<<' '<<arrw[i]<<' '<<arridx[i]<<' '<<arrsubNum[i]<<endl;
        cout<<arrsub[i][0]<<' '<<arrsub[i][1]<<endl;
    }
    cout<<minv<<endl;
*/
//solve
    int tmpN = N/10+1;
    int tmpm = m+1;
    int **dp;
    dp = new int* [tmpN];
    for(int i=0; i<tmpN; i++)
    {
        dp[i] = new int [tmpm];
    }

    //init
    for(int i=0; i<tmpN; i++)
    {
        dp[i][0] = 0;
    }
    for(int i=0; i<tmpN; i++)
    {
        for(int j=0; j<tmpm; j++)
        {
            if(i<minv)
            {
                dp[i][j] = 0;
            }
        }
    }
/*
    cout<<"init"<<endl;
*/
    //begin
    for(int i=minv; i<tmpN; i++)
    {
        for(int j=1; j<tmpm; j++)
        {
            if(arridx[j]==0)
            {
                int tmpmax;
                if(arrsubNum[j]==2)
                {
                    tmpmax = dp[i][j-1];
                    if(i >= arrv[j])
                        tmpmax = max(dp[i-arrv[j]][j-1] + arrv[j]*arrw[j] , tmpmax);
                    if(i >= arrv[j]+arrv[arrsub[j][0]])
                        tmpmax = max(dp[i-arrv[j]-arrv[arrsub[j][0]]][j-1] + arrv[j]*arrw[j] + arrv[arrsub[j][0]]*arrw[arrsub[j][0]] , tmpmax);
                    if(i >= arrv[j]+arrv[arrsub[j][1]])
                        tmpmax = max(dp[i-arrv[j]-arrv[arrsub[j][1]]][j-1] + arrv[j]*arrw[j] + arrv[arrsub[j][1]]*arrw[arrsub[j][1]] , tmpmax);
                    if(i >= arrv[j]+arrv[arrsub[j][0]]+arrv[arrsub[j][1]])
                        tmpmax = max(dp[i-arrv[j]-arrv[arrsub[j][0]]-arrv[arrsub[j][1]]][j-1] + arrv[j]*arrw[j] + arrv[arrsub[j][0]]*arrw[arrsub[j][0]]+ arrv[arrsub[j][1]]*arrw[arrsub[j][1]] , tmpmax);
                }
                else if(arrsubNum[j]==1)
                {
                    tmpmax = dp[i][j-1];
                    if(i >= arrv[j])
                        tmpmax = max(dp[i-arrv[j]][j-1] + arrv[j]*arrw[j] , tmpmax);
                    if(i >= arrv[j]+arrv[arrsub[j][0]])
                        tmpmax = max(dp[i-arrv[j]-arrv[arrsub[j][0]]][j-1] + arrv[j]*arrw[j] + arrv[arrsub[j][0]]*arrw[arrsub[j][0]] , tmpmax);
                }
                else
                {
                    tmpmax = dp[i][j-1];
                    if(i >= arrv[j])
                        tmpmax = max(dp[i-arrv[j]][j-1] + arrv[j]*arrw[j] , tmpmax);
                }

                dp[i][j] = tmpmax;
            }
            else
            {
                dp[i][j] = dp[i][j-1];
            }

        }
    }



    cout<<dp[tmpN-1][tmpm-1]*10<<endl;








    for(int i=0; i<tmpN; i++)
    {
        delete [] dp[i];
    }
    delete [] dp;



    delete [] arrv;
    delete [] arrw;
    delete [] arridx;

    for(int i=0; i<m+1; i++)
    {
        delete [] arrsub[i];
    }
    delete [] arrsub;
    delete [] arrsubNum;

    return 0;
}
相關文章
相關標籤/搜索