HDU3315 My Brute (求KM最大时,要求改动最少★★)
2015-09-01 12:56
417 查看
题意:两个人,有部下,每个部下有血量和伤害值,赢一场会得到该场的分数,每个部下只能参加一次。问怎么安排,部下与对方干,最后能有最多的分数。
思路:预处理各个部下对战能得到的分数,在KM,由前一题,我们知道,直接把权重放大K倍(K>n).原来的边权重加一。
思路:预处理各个部下对战能得到的分数,在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; }
相关文章推荐
- java基础
- “==”和Equals的区别
- Linux入门教程
- Hadoop学习笔记(十七)---Hive安装及配置
- Android Studio 导入 Eclipse 的代码后,代码中的注释显示乱码问题
- jquery中event对象属性与方法小结
- servlet+jsp+java实现Web 应用
- C++内存管理
- 安装intelhaxm出错,this computer does not support intel virtualization Technology(VT-x)
- 【leetcode每日一题】61.Rotate List
- C#------封装文件拷贝方法
- 博文收藏夹
- VMware Workstation 11
- 【Android进阶】-AIDL使用解析
- VS2010的代码粘贴到Word里面的汉字乱码
- 生鲜电商的七种模式分析
- ubuntu切换成root用户
- Linux:-bash: ***: command not found
- 大整数的加乘多项式运算
- C#中DataGridView常用操作实例小结