A,B,C,D水,跳
E枚举中间点,一边桶存,一边遍历就好了,在写个二维前缀和就过了
F比较有意思,发现n较小,还明显可以贪心,贪心条件就只剩下最后的票数,于是枚举最后票数,贪心
代码
#include <bits/stdc++.h>
using namespace std;
long long n, ls, ans = 114514, piao, cnt[2005], res, cc[2005], lp;
struct sd {
long long a, b;
} stu[2005];
int cmp(sd A, sd B) {
if (B.b != A.b)
return A.b < B.b;
else
return cnt[A.a] > cnt[B.a];
}
int main() {
cin >> n;
for (int i = 2; i <= n; i++) {
cin >> stu[i].a;
cnt[stu[i].a]++;
if (stu[i].a == 1)
piao++;
}
for (int i = 2; i <= n; i++) {
cin >> stu[i].b;
}
sort(stu + 2, stu + n + 1, cmp);
for (int i = piao; i <= n; i++) {
res = 0;
lp = piao;
for (int j = 2; j <= n; j++) {
if (cnt[stu[j].a] >= i && stu[j].a != 1) {
cnt[stu[j].a]--;
res += stu[j].b;
cc[j] = 1;
lp++;
}
}
for (int j = 2; j <= n; j++) {
if (lp >= i)
break;
if (cc[j] == 0 && stu[j].a != 1) {
cnt[stu[j].a]--;
res += stu[j].b;
cc[j] = 1;
lp++;
}
}
ans = min(ans, res);
for (int j = 2; j <= n; j++) {
if (cc[j] == 1) {
cnt[stu[j].a]++;
cc[j] = 0;
}
}
}
cout << ans;
return 0;
}