题目大意: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; }
CF 366C Dima and Salad [天平DP]
时间: 2024-09-29 19:43:21