题目大意:
n 个人 在选取班长 1号十分想当班长,他已经知道其他人选择了谁,但他可以贿赂其他人改选他,问贿赂的最小值
ps.他自己也要投一个人
要处理一个问题是,他自己投谁
其实这个问题在这种局面下在不同算法有不同处理方法,先不要考虑
一开始我想的是纯贪心:
选2个最小的比较票数最多中最小的 谁小选哪个
直到1号票数最多(但不是唯一)
这个时候再考虑 他投给谁
1.如果有一个人票数跟他一样多x ,这个时候1号还要拿一票,谁给他一票他就投给谁,不影响结果(给他同样票数的人,那个人票数不变,1号多了1票,所以也不变)
2.如果其他人票数都只比他少1 ,这个时候1号不需要拿票了,但他也必须投给一个人,会使得有人跟他一样,所以又要去拿一张最小的
3.其他情况投给票数比他少2的即可
但这样有反例
1
10
9 4 8 9 8 1 4 9 2
14 4 7 16 9 3 19 17 16
正解是 14+4;
而我的算法 先选了4+7,最后选了9 答案是20;
正确解法,枚举加贪心:
既然n<100 我应该就需要考虑到枚举or搜索的可能性,教训要牢记
枚举1获胜所得的票数p,在循环找所有大票大于p-1的人,从小到大给1,结束后超过p 表示不行
否则:在从小到大找几个填到p 更新ANS
对于1投给谁 ,只有这种情况有意义 1有p票 其他人p-1票
总票数 n*p-n+1+1(1的一票);
如果 p=1; 总票数 2 代表只有2个人 但是n>=3
如果 p=2; 总票数为n+2,超过了应该的总票数n
如果 p>2 于p=2同理 所以不需要考虑
代码如下:
//已知算法下 /* 1WA 原因 算法实现设计错误,最后一部,取k个最小的东西,可是因为按照优先序号排序的,所以算法与设计冲突 差错数据 6 1 2 2 3 3 7 8 9 1 1 正确: 2 错误 17 */ #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <ctime> #include <algorithm> #include <iostream> #include <sstream> #include <string> #define oo 0x13131313 using namespace std; void init() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); } const int maxn=100+5; struct node { int p,w; int ok; }; node A[maxn]; int piao[maxn]; int P[maxn]; void copy() { for(int i=0;i<maxn;i++) A[i].ok=1; for(int i=0;i<maxn;i++) P[i]=piao[i]; } int n; void input() { cin>>n; memset(piao,0,sizeof(piao)); for(int i = 1; i <= n - 1; i++) { scanf("%d",&A[i].p); piao[A[i].p]++; } for(int i = 1;i <= n - 1; i++) scanf("%d",&A[i].w); } bool cmp(node a,node b) { if(a.p==b.p) return a.w<b.w; else return a.p<b.p; } bool cmp2(node a,node b) { return a.w<b.w; } void solve() { int ans=100000000,tans=0; for(int i=piao[1];i<=n-1;i++) { sort(A+1,A+n,cmp); copy();tans=0; for(int j=1;j<=n-1;j++) { if(A[j].p!=1) { if(P[A[j].p]>i-1) { A[j].ok=0; tans+=A[j].w; P[A[j].p]--; P[1]++; } } } if(P[1]>i) continue; else { sort(A+1,A+n,cmp2); int tot=0; for(int j=1;j<=n-1;j++) if(tot<i-P[1]) if(A[j].p!=1) { if(A[j].ok==1) { tans+=A[j].w; tot++; } } } if(tans<ans) ans=tans; } printf("%d\n",ans); } int main() { // init(); int T; cin>>T; while(T--) { input(); solve(); } }