HDU3315 My Brute (求KM最大时,要求改动最少★★)
来源:互联网 发布:淘宝活动派发报名任务 编辑:程序博客网 时间:2024/06/16 21:07
题意:两个人,有部下,每个部下有血量和伤害值,赢一场会得到该场的分数,每个部下只能参加一次。问怎么安排,部下与对方干,最后能有最多的分数。
思路:预处理各个部下对战能得到的分数,在KM,由前一题,我们知道,直接把权重放大K倍(K>n).原来的边权重加一。
#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<set>#include<map>#include<string>#include<cstring>#include<stack>#include<queue>#include<vector>#include<cstdlib>#define lson (rt<<1),L,M#define rson (rt<<1|1),M+1,R#define M ((L+R)>>1)#define cl(a,b) memset(a,b,sizeof(a));#define LL long long#define P pair<int,int>#define X first#define Y second#define pb push_back#define fread(zcc) freopen(zcc,"r",stdin)#define fwrite(zcc) freopen(zcc,"w",stdout)using namespace std;const int maxn=100;const int inf=1<<28;int w[maxn][maxn];int linker[maxn],lx[maxn],ly[maxn],slack[maxn];bool visx[maxn],visy[maxn];int nx,ny;bool dfs(int x){ visx[x]=true; for(int i=0;i<ny;i++){ if(visy[i])continue; int tmp=lx[x]+ly[i]-w[x][i]; if(tmp==0){ visy[i]=true; if(linker[i]==-1||dfs(linker[i])){ linker[i]=x; return true; } }else if(slack[i]>tmp){ slack[i]=tmp; } } return false;}int km(){ cl(linker,-1); cl(ly,0); for(int i=0;i<nx;i++){ lx[i]=-inf; for(int j=0;j<ny;j++)if(w[i][j]>lx[i]){lx[i]=w[i][j];} } for(int x=0;x<nx;x++){ fill(slack,slack+ny+1,inf); while(true){ cl(visx,false); cl(visy,false); if(dfs(x))break; int d=inf; for(int i=0;i<ny;i++)if(!visy[i]&&slack[i]<d){ d=slack[i]; } for(int i=0;i<nx;i++)if(visx[i])lx[i]-=d; for(int i=0;i<ny;i++)if(visy[i])ly[i]+=d; else slack[i]-=d; } } int ans=0; //bool ok=false; for(int i=0;i<ny;i++)if(linker[i]!=-1){ ans+=w[linker[i]][i]; //if(w[linker[i]][i]==-inf)ok=true; } //if(ok)return 1; return ans;}int score[maxn],h[maxn],p[maxn],a[maxn],b[maxn];int main(){ int n; while(scanf("%d",&n)&&n){ for(int i=0;i<n;i++){ scanf("%d",&score[i]); } for(int i=0;i<n;i++){ scanf("%d",&h[i]); } for(int i=0;i<n;i++){ scanf("%d",&p[i]); } for(int i=0;i<n;i++){ scanf("%d",&a[i]); } for(int i=0;i<n;i++){ scanf("%d",&b[i]); } int k=n+10; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ int t1=(p[j]+a[i]-1)/a[i]; int t2=(h[i]+b[j]-1)/b[j]; if(t1<=t2){ w[i][j]=score[i]*k; } else { w[i][j]=-score[i]*k; } } } for(int i=0;i<n;i++){ w[i][i]+=1; } nx=n;ny=n; int ans=km(); if(ans>=0)printf("%d %.3lf%%\n",ans/k,double(ans%k)/double(n)*100.0); else printf("Oh, I lose my dear seaco!\n"); } return 0;}
0 0
- HDU3315 My Brute (求KM最大时,要求改动最少★★)
- ★ HDU 2853 求KM最大时,要求改动最少
- ★ HDU 3315 求KM最大时,要求改动最少
- HDU 2853 Assignment([好题] 求KM最大时,要求改动最少★★)
- #HDU3315#My Brute(Km+余数巧用)
- 【网络流】hdu3315 My Brute
- HDU 3315 My Brute(KM最大匹配)
- HDOJ 3315 - My Brute 维护两个最值..构图最大费用最大流 or KM模板
- HDU 3315 My Brute KM算法
- HDU 3315 My Brute(KM算法)
- hdu2853 Assignment (KM最少改动边)
- My Brute (hdu 3315 二分图最大权匹配KM算法)
- HDU 2853 Assignment 最大匹配+求最少改动的匹配数 之神奇建图
- My Brute
- HDU 3315 My Brute 费用流+求错位率(好题)
- km算法(求二分图带权的最大匹配)
- hdu3315My Brute KM算法
- HDU 3315 My Brute(费用流)
- Android Studio 导入 Eclipse 的代码后,代码中的注释显示乱码问题
- java基础
- NYOJ 119 士兵杀敌(三)(线段树--区间最值之差)
- 后缀表达式树
- “==”和Equals的区别
- HDU3315 My Brute (求KM最大时,要求改动最少★★)
- tcpdump抓包规则命令大全
- OAF学习笔记-15-大文本(过长,英文数字)在table 中换行显示
- 在 Unity 中使用 Android SDK
- ArrowDownloadButton下载按钮从点击到下载完成特效
- QT即时计时器
- hello, blog!
- 容斥原理的证明
- Oracle,实现一条记录的上移下移