codeforces-214(Div. 2)-C. Dima and Salad+DP恰好背包花费

codeforces-214(Div. 2)-C. Dima and Salad

题意:有不同的沙拉,对应不同的颜值和卡路里,现在要求取出总颜值尽可能高的沙拉,同时要满足

                       

解法:首先要把除法变成乘法,就是每次把读进来的b[ i ] 乘以 K;

   因为对于a [ i ] - b[ i ] * k有两种不同的可能(大于0和小于0),可以放在一个以25000为中心的,大小为50000的dp数组里;

   

  比如对于样例1:

  input

  3 2
  10 8 1
  2 7 1
  output
  18
这里我们缩小一下数据
我一开始不理解,为什么dp[j - b[i]]为什么只能在非-1的情况下更新dp[j];后来画了图就明白了;
下面ac代码:
//learnt and created at 2018/2/7
 #include <cstdio>
 #include <algorithm>
 #include <cstring>
 using namespace std;
 int n,k;
 int a[110],b[110];
 int dp[50020],mid = 25000;
 int main(){
    scanf("%d%d",&n,&k);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&b[i]);
        b[i] = a[i] - b[i]*k;
    }
    memset(dp,-1,sizeof(dp));        //把dp数组初始化为-1;只把dp[25000]=0;
    dp[mid]=0;
    for(int i=1; i<=n; i++)
    {
        if(b[i]>=0)
        {
            for(int j=50000; j>=b[i]; j--)
            {
                if(dp[j-b[i]] !=-1)
                    dp[j] = max(dp[j-b[i]]+a[i],dp[j]);
            }
        }
        else
        {
            for(int j=0; j<=50000+b[i]; j++)
            {
                if(dp[j-b[i]]!=-1)
                    dp[j] =max(dp[j-b[i]]+a[i],dp[j]);
            }
        }
    }
    if(dp[mid]==0)puts("-1");
    else printf("%d
",dp[mid]);

    return 0;
 }

  
  


skr
原文地址:https://www.cnblogs.com/ckxkexing/p/8427335.html