题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3632
题目大意:有N天,每天都可以买西瓜,每天买西瓜都有一个花费vi,和这个西瓜能吃的天数idi,问保证每天都有西瓜吃的最小花费(当某个西瓜买之后之前的西瓜就不能吃了)
解题思路:现在我们用dp【i】表示前i天都有西瓜吃的最小花费,那我们只需要对于 每天的西瓜 更新加入这个西瓜的花费和能吃到的天数,然后把它加入优先队列,然后从队列中查找满足前i天都有西瓜吃的第一个值,即最小花费,更新dp【i】的值,对于不满足的直接pop出来,那么更新完后dp【n】即为所求最小花费。
代码如下:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#define N 50005
using namespace std;
int v[N],id[N];
long long dp[N];
struct node
{
long long v;
int id;
bool operator <(const node& a) const
{
return v > a.v;//价值小的优先级高
}
};
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i = 1; i <= n; i ++)
scanf("%d",&v[i]);
for(int i = 1; i <= n; i ++)
scanf("%d",&id[i]);
priority_queue<node> q;
node temp;
dp[1] = v[1];
temp.v = v[1];temp.id = id[1];
q.push(temp);
for(int i = 2; i <= n; i ++)
{
temp.v = dp[i - 1] + v[i];
temp.id = i+id[i]- 1;
q.push(temp);
while(q.top().id < i) q.pop();
dp[i] = q.top().v;
}
printf("%lld\n",dp[n]);
}
return 0;
}