You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
2.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
int n, k, sum;
int c[101]; //价钱
int num[101]; //
int m[101]; //美味价值
int f[1001], number, bi;
bool b[101]; //b数组是由来确定他是否为已处理过的必选菜。
//01背包问题注意两个小问题就好了:
// 1.把价格和money都扩大十倍。
// 2.同一物品会出现两次然并卵。所幸题目提示了用种类哈希数组映射到vis上去就好了如果是必选物品i就设置vis[i]为0。
int main() {
//输入+输出重定向
freopen("../1300.txt", "r", stdin);
//b数组是由来确定他是否为已处理过的必选菜。
memset(b, false, sizeof(b));
//有n个菜式有k种菜是必选的小松带来了X元钱精确到“角”
double x;
scanf("%d%d%lf", &n, &k, &x);
int tot = (int) (x * 10);//为了方便处理在这里我们把价钱全部乘10。
//表示菜桌上从入口到出口的所有菜的价格
//由于价钱是精确到角的,所以这里*10不影响该题的答案
double a;
for (int i = 1; i <= n; i++) {
scanf("%lf", &a);
c[i] = (int) (a * 10);
}
//表示菜桌上从入口到出口的所有菜的美味价值
for (int i = 1; i <= n; i++)
scanf("%d", &m[i]);
//表示菜桌上从入口到出口的所有菜的种类编号
for (int i = 1; i <= n; i++) {
scanf("%d", &number);
num[number] = i;//编号相同的菜后来的会覆盖掉前面的,这样接下来处理就简单了
} //在这个地方我们把输入的数当成下标,存放下标的位置,就很容易寻找它对应的价值和美味值..
for (int i = 1; i <= k; i++) {
scanf("%d", &bi);//读入种类
tot -= c[num[bi]]; //根据种类,换算出价格
sum += m[num[bi]]; //根据种类,换算出美味值
b[bi] = true; //注意在这个时候b[]内是bi;
}
//tot就是上限的价格也可以理解为就是背包的上限容量
//sum就是最终的美味值和目前只是必选菜的美味值和
//01背包
for (int i = 1; i <= n; i++)
if (!b[i]) //如果不是必选菜才能进行01背包处理
for (int j = tot; j >= c[num[i]]; j--) {
f[j] = max(f[j], f[j - c[num[i]]] + m[num[i]]);//01背包求解
}
//输出结果
printf("%d", f[tot] + sum);
//关闭文件
fclose(stdin);
return 0;
}