C - 召唤猫咪

描述

你是一名猫咪魔法师,现在想要召唤猫咪。

有一条路,路上有 n 棵树,每颗树上有 \({c_i}\) 只猫咪。你在树底下可以花费 \({cost_i}\) 点蓝量召唤一直猫咪,每召唤一只猫咪,你的蓝量上限增加 B(不增加蓝量),从一颗树走到下一棵树,你会回复 X 点蓝量。你的初始蓝量和上限都是 W ,你的蓝量不能超过上限,你只能从第一棵树开始走。

你能最多召唤多少只猫咪?

输入

第一行包含四个整数 n,W,B,X(1≤n≤\({10^3}\),0≤W,B,X≤\({10^9}\))—树的数量,法力的初始点,召唤一只猫咪之后法力上限增加的点数,当从一棵树移到下一棵树时,蓝量恢复的数量。

第二行包含 n 个整数\({ c_1,c_2,...,c_n(0≤c_i≤10^4}\))其中 c_i 是生活在第 ii个树中的猫咪的数量。 可以保证 \({∑^n_i c_i <= 10^4}\)

第三行包含 n 个整数,分别为\({cost_1,cost_2,...,cost_n(0≤cost_i≤10^9)}\)其中&{cost_i}$是从第 i 个树召唤一只猫咪的法力消耗。

输出

输出一个整数--你所能召唤最大的猫咪数量。

样例

2 12 0 4
3 4
4 2
6
5 1 4 6
3 4 6 5 1
3 0 10 2 9
10

提示

【样例解释】

在第一棵树召唤两只猫咪,剩余法力值4点,走到下棵树,法力值为8点,召唤4只猫咪,总共6只猫咪。

【数据说明】

对于20%的数据: \({1 \le n \le 101≤n≤10 }\)

对于60%的数据: \({1 \le n \le 1001≤n≤100 }\)

对于100%的数据: \({1 \le n \le 10001≤n≤1000 }\)

题解

从本意出发
需要枚举:
1. 第i棵树
2. 目前有多少猫了
3. 这棵树上选多少猫
第3维可以省去
直接3个循环 冲冲冲

开long long注意!

CODE

AC代码

#include <bits/stdc++.h>
using namespace std;
const int N = 10001;
#define rep(a, b, c) for(int a = b; a <= c; a++)
#define dep(a, b, c) for(int a = b; a >= c; a--)

long long n, w, b, x, c[N], cost[N], num;
long long dp[1001][N];
//dp[i][j]前i棵树 j只猫 

int main(){
	scanf("%lld%lld%lld%lld", &n, &w, &b, &x);
	rep(i, 1, n){
		scanf("%lld", &c[i]);
	}
	rep(i, 1, n){
		scanf("%lld", &cost[i]);
	}
	memset(dp, -1, sizeof(dp));
	dp[0][0] = w;
	rep(i, 1, n){//枚举树
		num += c[i];
		rep(j, 0, num){//枚举猫
			rep(k, 0, j){//枚举当前树的猫
				if(k > c[i]){//这棵树上的猫选完了 
					break;
				} 
				if(dp[i - 1][j - k] == -1){//没蓝了 建议回家 
					continue;
				}
				if(dp[i - 1][j - k] < k * cost[i]){//需要回蓝 建议打蓝bafu 
					continue;
				}
				dp[i][j] = max(dp[i][j], min(dp[i - 1][j - k] - k * cost[i] + x, w + j * b));
				//有蓝,杀鸡!
				//后面取个min是因为不能超过上限蓝量 
			} 
		} 
	}
	int ans = 0;
	rep(i, 0, num){//找有可能的取猫的数量 
		if(dp[n][i] > 0){
			ans = i;
		}
	}
	printf("%d\n", ans);
	return 0;
} 
posted @ 2020-10-27 20:23  LT-Y  阅读(162)  评论(0编辑  收藏  举报