首页 > 代码库 > CF 366C Dima and Salad [天平DP]

CF 366C Dima and Salad [天平DP]

题目大意:n个水果,水果有甜度和卡路里两个属性,选择一些水果,使得甜度之和与卡路里之和比例为k,并且使得甜度之和最大

我们可以定义二维dp,dp[当前游标扫到的个数][平衡度]=当前平衡度下最大的ai和,平衡度定义为ai-bi*k,很巧秒的定义方式,可以节省一维时空。

注意到平衡度可正可负(范围在-10000到10000)

我们可以定义如下

int m[1111][22222]

int *d[i]=&m[i][10000]

dp[num+1][balance]=max(self,dp[num][balance]);dp[num+1][balance+a[i]-b[i]*k]=max(self,dp[num][balance]+a[i])

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
int m[1111][22222];
int* d[1111];
int a[1111];
int b[1111];
int main(){
#ifndef ONLINE_JUDGE
	freopen("/home/rainto96/in.txt","r",stdin);
#endif

	int n,k;
	cin>>n>>k;
	memset(m,-1,sizeof(m));
	for(int i=0;i<=n;i++){
		d[i]=&m[i][10000];
	}
	d[0][0]=0;
	for(int i=1;i<=n;i++)
		cin>>a[i];
    for(int i=1;i<=n;i++)
		cin>>b[i];
	for(int i=0;i<n;i++){
		for(int j=-10000;j<=10000;j++){
			if(d[i][j]!=-1){
				d[i+1][j]=max(d[i+1][j],d[i][j]);
				int get=j+a[i+1]-b[i+1]*k;
				d[i+1][get]=max(d[i+1][get],d[i][j]+a[i+1]);
			}
		}
	}
	if(d[n][0]!=0)
        cout<<d[n][0]<<endl;
    else
        cout<<-1<<endl;
}