洛谷P2998 Candy S

题目描述

Farmer John knows that Bessie loves to eat candy. FJ has N (1 <= N <= 40,000) candies that he wants to give Bessie over some number of days. Each day, Farmer John gives Bessie a choice of how many candies she chooses to eat that day by choosing the number from a master list FJ supplies that has Nopt (1 <= Nopt <= 50) different options, C_i (1 <= C_i <= N). She must take exactly C_i candies, no more, no less.

Farmer John has also disclosed F (1 <= F <= 50) of his favorite numbers, FN_i (1 <= FN_i <= N). Whenever the number of candies remaining at the end of the day precisely matches one of these favorite numbers, Bessie has the option to have him add exactly M (1 <= M <= 100) more candies to the candy supply. Bessie might get another option to add M candies several times if adding candies creates another favorite number. In the best circumstances, Bessie can obtain an infinite amount of candy!

When Bessie cannot choose some amount of candy to take (because there is not enough), and the number of candies remaining is not any of FJ's favorite numbers, she cannot have any more candy.

Unfortunately, Bessie cannot think ahead as far as she'd like to, so she needs your help in order to eat as many candies as possible.

By way of example, consider this scenario:

* Farmer John's basket initially contains 10 candies

* Bessie can chose to eat either 3 or 5 candies each day

* Farmer John will add 1 candy any time the remaining number of candies is 2 or 4

Bessie could use this set of choices to maximize the amount of candy she can eat:


                  Initial      # Candies   Remaining     Bonus     Final
        Day      # Candies       Eaten      Candies     Candies   Candies

         1          10             3          7            0        7
         2           7             3          4            1        5
         3           5             3          2            1        3
         4           3             3          0            0        0

Total candies eaten = 3 + 3 + 3 + 3 = 12.

农民约翰知道Bessie喜欢吃糖果。约翰有N(1≤N≤40000)的糖果,他想给Bessie几天。每一天,贝茜从一个列表(有nopt(1 <= nopt <= 50)种不同的选择),选择那一天吃掉刚好C_i(1 <= c_i <= N)个糖果。

农民约翰也透露F(1≤f≤50)他最喜欢的数字,FN_i(1 <= FN_i <= N)。当当天最后剩下的糖果数量精确匹配其中一个喜欢的号码,Bessie可以让他添加恰好M(1 <= M = 100)个糖果。如果加后得到的个数,还是FJ喜欢的数字,就可以继续添加糖果M个(加几次由贝西决定)。在最好的情况下,Bessie可以吃掉无限量的糖果!

当Bessie不能选择一定量的糖(因为没有足够的),或者糖果的剩余数量不是任何约翰最喜欢的号码,她不能有任何更多的糖果。

不幸的是,Bessie想不出她想做的事,所以她需要你的帮助才能吃尽可能多的糖果。

输入格式

* Line 1: Four space-separated integers: N, Nopt, F, and M

* Lines 2..Nopt+1: Line i+1 contains a single integer: C_i

* Lines Nopt+2..Nopt+F+1: Line i+Nopt+1 contains a single integer: FN_i

1行:四个整数N,Nopt,F和M

2行。nopt + 1:i+ 1行包含一个整数:c_i

nopt + 2 .. nopt + F + 1 + 1 + nopt行:行包含一个整数:fn_i

输出格式

* Line 1: A single integer, denoting the maximum amount of candies Bessie can eat, or -1 if Bessie can eat an infinite amount of candy.

1行:一个整数,表示Bessie最多可以吃几个。如果Bessie可以无限量吃糖输出-1。

输入输出样例

输入 #1复制

10 2 2 1 
3 
5 
4 
2 

输出 #1复制

12 

上代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define inf 0x7f7f7f7f
#define N 60
using namespace std;
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int n,nopt,F,m,c[N],f[N],book[40110],dp[40110],cnt[40110],ans;

int main(){
	n=read(),nopt=read(),F=read(),m=read();
	for(int i=1;i<=nopt;i++) c[i]=read();
	for(int i=1;i<=F;i++) book[read()]=1;
	memset(dp,-1,sizeof(dp));
	dp[n]=0;book[n]=false;
	for(int i=n;i;i--){
		if(dp[i]==-1) continue;
		if(cnt[i]>F+1) return printf("-1\n"),0;
		if(book[i]){
			cnt[i]++;
			if(dp[i]>dp[i+m]){
				dp[i+m]=dp[i];
				i+=m+1;
			}
			continue;
		}
		for(int j=1;j<=nopt;j++){
			if(i-c[j]<0) continue;
			dp[i-c[j]]=max(dp[i-c[j]],dp[i]+c[j]);
		}
	}
	for(int i=n;i>=0;i--) ans=max(ans,dp[i]);
	printf("%d\n",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值