养猪_lduoj_dp
Description
你有一个猪圈,有N头猪,每天你最多可以杀一头猪卖钱,获益就是猪的体重。但是每过一天每头猪的体重都会下降P[i](当然,如果猪体重≤0了,自然获利为0),问K天内你的最大获利。
Input
第一行两个数N,K;
第二行N个数,表示猪的初始重量A[i];
第三行N个数表示P[i]。
Output
一行一个数表示最大获利。
Samples
Input Copy
2 2
10 10
1 2
Output
19
Hint
对于20%的数据,满足1≤N≤20;
对于100%的数据,满足1≤N≤1000,初始重量≤105.
刚开始有一种方法,将输入的数据首先按照体重进行排序,如果体重相同就按照体重减小的程度从大到小进行排序(这样可以在遍历的过程中首先取容易贬值的),这样可以满足一个当前状态来看比较优的情况,然后wa掉了。
上面的方法Wa掉之后以为是在取了一个之后,其余的元素减少的值可能会引起他们大小的改变,所以说写了一个优先队列,定义一种优先的顺序,可以在每次取元素的时候得到当前值最大的,并在每次操作之后将里面的元素减掉一个减少的值,然后重新放到队列里面(用栈stack和优先队列priority_queue),然后还是wa掉了
这时就考虑了方法的正确性:当前这一步的最优会干扰其他的元素的值进行减小,当前的操作会影响后面还没有选过的,并干扰全局最优的情况,所以说要考虑使用动态规划的方法来进行处理该题
在处理数据的时候要注意按照猪体重减小的顺序进行排序,如果说体重减小得快,就要先对他进行处理,如果说体重减小的比较慢就对他进行后处理
因为排序的方法的原因,所以在得到的dp数组中的值可能不会出现在最后面,要遍历数组或者是排序后输出最大元素
ll n , m;
ll ans;
struct node{
ll x;
ll y;
}a[1007];
bool cmp(node a,node b){
if(a.y != b.y) return a.y > b.y;
else return a.x > b.y;
/**
if(a.x != b.x) return a.x > b.x;
else return a.y > b.y;
**/
}
ll dp[maxn];
int main()
{
n = read,m=read;
for(int i=1;i<=n;i++) a[i].x = read;
for(int i=1;i<=n;i++) a[i].y = read;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
for(int j=m;j>=1;j--){
ll temp = a[i].x - a[i].y * (j-1);
if(temp < 0) temp = 0;
dp[j] = max(dp[j-1] + temp,dp[j]);
}
}
for(int i=1;i<=m;i++) ans = max(ans,dp[i]);
cout << ans <<endl;
return 0;
}