题目链接:https://qduoj.com/problem/133/点击打开链接
Problem Description
LYD loves codeforces since there are many Russian contests. In an contest lasting for T minutes there are n problems, and for theith problem you can get ai−di∗ti points, where ai indicates the initial points, di indicates the points decreased per minute (count from the beginning of the contest), and ti stands for the passed minutes when you solved the problem (count from the begining of the contest).
Now you know LYD can solve the ith problem in ci minutes. He can't perform as a multi-core processor, so he can think of only one problem at a moment. Can you help him get as many points as he can?
Input
The first line contains two integers n,T(0≤n≤2000,0≤T≤5000).
The second line contains n integers a1,a2,..,an(0<ai≤6000).
The third line contains n integers d1,d2,..,dn(0<di≤50).
The forth line contains n integers c1,c2,..,cn(0<ci≤400).
Output
Output an integer in a single line, indicating the maximum points LYD can get.
Example Input
3 10 100 200 250 5 6 7 2 4 10
Example Output
254
关键说说本题排序的问题和为什么要排序
一开始看到题有贪心取背包的感觉 问题是怎么贪心
如果单纯判断一个变量 比如每道题中该题每分钟掉分的分数 或者只考虑时间 都会因为另一个因素影响而到不到最优
取两道题的例子研究
设第一题的分数为v1 每分钟掉d1 需要t1分钟
设第二题的分数为v2 每分钟掉d2 需要t2分钟
先1后2的得到分数的情况是:sum1=( v1 - d1 * t1 ) + ( v2 - d2 * ( t2 + t1 ) )
先2后1的得到分数的情况是:sum2=( v2 - d2 * t2 ) + ( v1 - d1 * ( t1 + t2 ) )
另dif=sum1-sum2 自己纸上算一算 得到式子dif = d1 * t2 - d2 * t1
当dif > 0 即sum1>sum2 即 先取1所得到的分数大于先取2所得到的分数的时候 就应该满足 d1 * t2 > d2 * t1 (dif = d1 * t2 - d2 * t1 > 0推出来的) 变换得到d1 / t1 > d2 / t2
由于博主语文不大好 比较难用文字表达出容易让人理解的意思 。。各位自行感受上一行最后一个表达式的含义
虽然不能理解意思 但是可以得到这样一个结论:当d1 / t1 > d2 / t2时 先取1后取2更优
那么能够推出的结论就是 对于任意第i道题 di / ti值越大 就需要越先解决这道题
很明显了 通过额外记录一个judge=di / ti 对judge从大到小排序 然后进行01背包的动态规划
#include <iostream>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <limits>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#define maxn 100010
using namespace std;
struct xjy
{
int weight;
int total;
int decrese;
double judge;
bool operator < (const xjy &r)const
{
return judge<r.judge;
}
};
xjy a[2222];
int dp[maxn];
int main()
{
memset(dp,0,sizeof(dp));
int n,t;
scanf("%d%d",&n,&t);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i].total);
}
for(int i=0;i<n;i++)
{
scanf("%d",&a[i].decrese);
}
for(int i=0;i<n;i++)
{
scanf("%d",&a[i].weight);
}
for(int i=0;i<n;i++)
{
a[i].judge=(a[i].weight*1.0)/a[i].decrese;
}
sort(a,a+n);
int ans=0;
for(int i=0;i<n;i++)
for(int j=t;j>=a[i].weight;j--)
{
dp[j]=max(dp[j],dp[j-a[i].weight]+a[i].total-a[i].decrese*j);
ans=max(ans,dp[j]);
}
cout << ans << endl;
return 0;
}