Buyer

解题思路

当j-w[i]>=0时 f[i][j]=max(f[i-1][j] , v[i]+f[i-1][j-w[i])

当j-w[i]<0时 f[i][j]=f[i-1][j]

通过公式建立动态规划表

用回溯法求最优解

思路

0—1背包类问题:有N件物品和一个容量为V的背包。第i件物品的价格(即体积,下同)是w[i],价值是c[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

相当于用f[i][j]表示前i个背包装入容量为v的背包中所可以获得的最大价值。

对于一个物品,只有两种情况

  一: 第i件不放进去,这时所得价值为:f[i-1][v]

  二: 第i件放进去,这时所得价值为:f[i-1][v-c[i]]+w[i]

状态转移方程为:f[i][v] = max(f[i-1][v], f[i-1][v-w[i]]+c[i])

#include<iostream>
using namespace std;
int main()
{
    int s,n;
    while(cin>>s>>n)
    {
        int w[1000]={0},v[1000]={0},a[100][100]={0},i,j,c[101]={0},k;
        k=1;
        for(i=1;i<=n;i++)
        {
            cin>>w[i]>>v[i];
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=s;j++)
            {

                if(j-w[i]>=0)
                {
                    if(a[i-1][j]>=(a[i-1][j-w[i]]+v[i]))
                    {
                        a[i][j]=a[i-1][j];

                    }
                    else
                        a[i][j]=a[i-1][j-w[i]]+v[i];

                }
                else
                    a[i][j]=a[i-1][j];
            }  
        }

        if(a[n][s]!=0)
        {
        cout<<a[n][s]<<endl;
        for(i=n,j=s;i>=1&&j>=1;)
        {
            if(a[i][j]>a[i-1][j])
            {
            c[k]=i;
            k++;

                j=j-w[i];
                i=i-1;

            }
            else
            {
                i=i-1;
            }


        }

    for(i=100;i>=0;i--)
    {
        if(c[i]>0)
        {
        cout<<c[i];
        if(i!=1)
            cout<<" ";
        }

    }
        }
        else
            cout<<"0";
        cout<<endl;

    }
    return 0;
}

results matching ""

    No results matching ""