10347 忙碌又贪心的泥瓦匠

来源:互联网 发布:类似于onedrive的软件 编辑:程序博客网 时间:2024/06/07 07:44

Description

村里有唯一一个泥瓦匠叫Kemo,很多人需要找Kemo修房子、修灶台、造花园……等,大家可以向Kemo预约修葺的时间和工钱。现在情况是:1)Kemo只有一个人,不能同时为两个雇主工作2)Kemo只有干完一个雇主家的活才可以在接下来的一天切换到另一个雇主家里干活。未干完一份活不可以离开,不可以为多位雇主交叉时间干活3)Kemo如果不能在预约的时间那天应约的话,这个雇主的这份钱就挣不到了Kemo比较聪明,他把大家的预约收集好,想让自己忙碌一阵子,赚最多的钱。现在请你为这个忙碌而又贪心的Kemo设计一个思路吧。

输入格式

输入4行:第一行,一个数字,n,表示n个人向Kemo预约需要修葺(n<=100)第二行,n个正数,表示这n个人所需完成修葺的时间的起始点。若时间点为8,表示第8天开始第三行,n个正数,表示这n个人所需完成修葺的工程天数。若天数为3,表示这一工程必须维持3天完成(所有工程都可以在第1000天内完成,即起始点+工期<=1000)第四行,n个正数,表示这n个人能向Kemo付出的工钱,工钱以每天计


输出格式

输出:忙完这阵子,Kemo最多能挣多少钱?例如:4个人需要找Kemo修葺,起始时间、工期和每天的工钱分别是:1 3 8 43 2 3 25 6 10 7则:Kemo可以获得的最大收益为:5*3+10*3+7*2 = 59


输入样例

41 3 8 43 2 3 25 6 10 7


输出样例

59



第一眼看到这道题就感觉这难道不是动态规划的题吗,也挺疑惑这道题为什么是放在搜索的栏目下(后来看到网上的确有深搜的做法
,这里就不多提这个了),我的做法是利用动态规划的思想,可以看到题目已经说明了所有工程都可以在1000天以内完成,所以很容易找到状态,即可以用dp[i]来表示前i天所能获得的最大工钱数,具体转移如下:
初值dp[i] = 0; dp[i] = max(d[k].val*d[k].num+dp[d[k].start-1],dp[i]); (k作为i天内完成的最后一个项目)
下面是我的源代码:

#include <algorithm>#include <iostream>#include <cstdio>#include <vector>#include <cstring>#include <cstdlib>#include <queue>#include <stack>#include <utility>#include <cmath>#include <map>#include <set>#define ll long long#define rep(i,n) for(int i=1;i<=n;i++)#define repn(i,n) for(int i=n;i>=1;i--)#define mst(a,x) memset(a,x,sizeof(a))const double esp = 1e-9;const double pi = acos(-1.0);const int INF = 0x3f3f3f3f;const int maxn = 100+100;const int maxm = 1000+100;using namespace std;struct node{    int start,end,len;    int val;}d[maxn];int dp[maxm];int main(){#ifdef local    freopen("in.txt","r",stdin);#endif    int n;scanf("%d",&n);    rep(i,n) scanf("%d",&d[i].start);    rep(i,n) scanf("%d",&d[i].len),d[i].end = d[i].start+d[i].len-1;    rep(i,n) scanf("%d",&d[i].val);    int ans = 0;    for(int i=0;i<maxm;i++){        for(int j=1;j<=n;j++){            if(d[j].end<=i)dp[i] = max(dp[i],dp[d[j].start-1]+d[j].val*d[j].len);        }        ans = max(ans,dp[i]);    }    printf("%d\n",ans);}



原创粉丝点击