题目大意:
从k个男生里面挑n个,每天只能挑选一个,在n天挑选完,每个男生魅力值为Li,每过一天,魅力值会下降Bi,问最终如何得到最大的魅力值和。
(不得不说hdu的出题人SangXinBingKuang)
一看就是dp的题,不过状态方程还是想了好一会。
这道题让我学了一手二维数组如何排序。
二维数组->结构体->vector->sort排序(自己写cmp函数)
这个方法可以推广到多维和字符串与数值相关的排序。
struct ki
{
int l;
int b;
};
bool cmp(struct ki x, struct ki y) //按b的降序
{
if(x.b > y.b)
return true;
return false;
}
vector<struct ki> p(1001);
sort(p.begin(), p.end(), cmp);
读一下这句话,每天选一个,n天选完,是不是很像01背包,只不过值是变化的。 不过问题不大。略作修改就好。
状态转移方程为:dp[j] = max(dp[j], dp[j-1] + p[i].l-(j-1)*p[i].b);
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
struct ki
{
int l;
int b;
};
bool cmp(struct ki x, struct ki y) //按b的降序
{
if(x.b > y.b)
return true;
return false;
}
int main()
{
int n,k;
while(scanf("%d%d",&n,&k) != EOF)
{
vector<struct ki> p(1001);
int dp[1001];
memset(dp,0,sizeof(dp));
for(int i=0; i<n; i++)
scanf("%d",&p[i].l);
for(int i=0; i<n; i++)
scanf("%d",&p[i].b);
sort(p.begin(), p.end(), cmp);
for(int i=0; i<n; i++)
{
for(int j=k; j>=1; j--)
{
dp[j] = max(dp[j], dp[j-1] + p[i].l-(j-1)*p[i].b);
}
}
printf("%d\n",dp[k]);
}
return 0;
}