$n \leq 40$个人玩$m \leq 10$台游戏机,每台游戏机一秒内只能一人玩,每人一秒内只能玩一台。每台游戏机有个价格,在规定总价格内可以把一部分游戏机复制一次,每台只能复制一次。给每个人对在每台游戏机上的需求时间,求一种方案使得所有玩游戏结束的时间尽量早。每个人每台游戏需求时间$\leq 2500$。

先不考虑复制。$R_i$表示人$i$玩游戏总时间,$C_j$表示机器$j$被玩总时间。可以发现答案的下界是$max(max(R_i),max(C_j))$,叫$T$。然后把人和机器建一个二分图,保证每个点的度数为$T$,就能在上面不停地做最大匹配,就可以把答案定为$T$。这里这么搞:左边$n$个人和$m$个假人,右边$m$台机器和$n$个假机器,假的东西用来补度数。然后,两边会连四种边:(1)真人真机器,连很多条边,边数为对应时间(其实可以连一条边记一个边权);(2)假人真机器,如果那个机器的度数不到$T$,那它肯定有一段空闲时间为$T-C_j$,这么多条边连向他对应的假人;(3)真人假机器,同(2);(4)假人假机器,这时假人和假机器的度数不到$T$,可以把真人真机器的图复制一遍把每个点度数补到$T$。把“连很多条边”搞成“连一条边,记个边权”,每次做完最大匹配后把所有边权减去匹配边中最小的那一个,然后把边权为0的边删掉。此时如果一条匹配边左右两边都是真人真机器,把这个操作记录下来,以此输出方案。

然后是钱的问题。当$T$为某个$C_j$时钱有用,此时若有钱就复制他,把机器的被玩时间均分成两份,使得$T$变小。

 //#include<iostream>
#include<cstring>
#include<cstdio>
//#include<time.h>
//#include<complex>
//#include<set>
//#include<queue>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n,m,B;
int a[],t[][],R[],C[]; bool co[];
struct Node{int a,b,c,d;}ans[]; int lans=; struct BG
{
int mp[][],p[],q[],n; bool vis[];
void clear(int N) {n=N;}
bool Pei(int x)
{
vis[x]=;
for (int i=;i<=n;i++) if (mp[x][i] && !q[i])
{
p[x]=i; q[i]=x;
return ;
}
for (int i=;i<=n;i++) if (mp[x][i] && q[i] && !vis[q[i]] && Pei(q[i]))
{
p[x]=i; q[i]=x;
return ;
}
return ;
}
void pei(int x) {memset(vis,,sizeof(vis)); Pei(x);}
}g; int main()
{
n=qread(); m=qread(); B=qread();
for (int i=;i<=m;i++) a[i]=qread();
for (int i=,x;i<=n;i++)
{
x=qread();
for (int j=,u,v;j<=x;j++)
{
u=qread(); v=qread();
t[i][u]=v;
}
} for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
R[i]+=t[i][j],C[j]+=t[i][j];
int T=,maxr=;
for (int i=;i<=n;i++) maxr=max(maxr,R[i]);
for (int j=;j<=m;j++) T=max(T,C[j]); T=max(T,maxr);
while (B)
{
int id=;
for (int j=;j<=m;j++) if (T==C[j] && co[j]) {id=-; break;}
if (id==-) break;
for (int j=;j<=m;j++) if (T==C[j]) {id=j; break;}
if (!id) break;
if (a[id]>B) break; int tot=T>>;
for (int i=;i<=n;i++)
{
if (tot<t[i][id]) {t[i][id+m]=tot; t[i][id]-=tot; break;}
else {tot-=t[i][id]; t[i][id+m]=t[i][id]; t[i][id]=;}
} co[id]=; B-=a[id];
C[id]=; for (int i=;i<=n;i++) C[id]+=t[i][id];
C[id+m]=; for (int i=;i<=n;i++) C[id+m]+=t[i][id+m];
T=; for (int j=;j<=m;j++) T=max(T,C[j]); T=max(T,maxr);
} g.clear(n+m+m);
for (int i=;i<=n;i++)
for (int j=;j<=m+m;j++) if (t[i][j])
g.mp[i][j]=g.mp[j+n][i+m+m]=t[i][j];
for (int i=;i<=n;i++) if (R[i]<T) g.mp[i][i+m+m]=T-R[i];
for (int j=;j<=m+m;j++) if (C[j]<T) g.mp[j+n][j]=T-C[j]; printf("%d\n",T);
for (int j=;j<=m;j++) printf("%d",co[j]); puts("");
lans=;
for (int i=;i<=n+m+m;i++) g.pei(i);
while (T)
{
int tmp=0x3f3f3f3f;
for (int i=;i<=n+m+m;i++) tmp=min(tmp,g.mp[i][g.p[i]]);
for (int i=;i<=n;i++) if (g.p[i]<=m+m)
ans[++lans]=(Node){i,g.p[i]<=m?g.p[i]:g.p[i]-m,T-tmp,tmp};
for (int i=;i<=n+m+m;i++) g.mp[i][g.p[i]]-=tmp;
for (int i=;i<=n+m+m;i++) if (g.mp[i][g.p[i]]==) {g.q[g.p[i]]=; g.p[i]=; g.pei(i);}
T-=tmp;
} printf("%d\n",lans);
for (int i=;i<=lans;i++) printf("%d %d %d %d\n",ans[i].a,ans[i].b,ans[i].c,ans[i].d);
return ;
}

Codeforces737E. Tanya is 5!的更多相关文章

  1. CodeForces 518B. Tanya and Postcard

    B. Tanya and Postcard time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  2. codeforces 518B. Tanya and Postcard 解题报告

    题目链接:http://codeforces.com/problemset/problem/518/B 题目意思:给出字符串 s 和 t,如果 t 中有跟 s 完全相同的字母,数量等于或者多过 s,就 ...

  3. Codeforces Round #288 (Div. 2)D. Tanya and Password 欧拉通路

    D. Tanya and Password Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/508 ...

  4. CF Tanya and Postcard

    Tanya and Postcard time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  5. Codeforces Round #324 (Div. 2) B. Kolya and Tanya 快速幂

    B. Kolya and Tanya Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/584/pro ...

  6. CodeForces - 508D Tanya and Password(欧拉通路)

    Description While dad was at work, a little girl Tanya decided to play with dad characters. She has ...

  7. Codeforces Round #346 (Div. 2) C Tanya and Toys

    C. Tanya and Toys 题目链接http://codeforces.com/contest/659/problem/C Description In Berland recently a ...

  8. 2016NEFU集训第n+3场 G - Tanya and Toys

    Description In Berland recently a new collection of toys went on sale. This collection consists of 1 ...

  9. codeforce round#466(div.2) B. Our Tanya is Crying Out Loud

    B. Our Tanya is Crying Out Loud time limit per test1 second memory limit per test256 megabytes input ...

随机推荐

  1. (转)SpringMVC学习(一)——SpringMVC介绍与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/72231272 SpringMVC介绍 SpringMVC是什么? SpringMVC和Stru ...

  2. UVA 11324 The Largest Clique (强连通分量,dp)

    给出一个有向图,求一个最大的结点集合,任意两个点u,v.u可到达v或v可到达u. 一个强连通分量肯定一起选的.而且只能在一条路径上. 所以先找出所有scc,然后缩点找一条最大权的路径,按拓扑序跑DAG ...

  3. 用dfs求联通块(UVa572)

    一.题目 输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块.如果两个字符所在的格子相邻(横.竖.或者对角线方向),就说它们属于同一个八连块. 二.解题思路 和前面的二叉树遍历类似,图也有DF ...

  4. html输入框去除记忆功能

    自动完成功能,只需把AUTOCOMPLETE设为off即可,如: 整个表单禁止自动完成 HTML code <FORM method=post action="submit.asp&q ...

  5. Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币

    什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...

  6. OC各种遍历方法的效率比较

    看了一篇博客,挺有意思,OC各种遍历方法的效率,打算自己也测试一番.看看,究竟哪一个的效率更好一些! 准备工作:懒加载一个数组,创建一千万个对象添加到数组. #pragma mark - Lazy M ...

  7. js最高效的数组去重方法

    var arr=[1,2,33,2,4,5,33,5,7,8,1,3];var result=[];var temp={};for( var i=0;i<arr.length;i++){ if( ...

  8. C++系统学习之六:函数

    1.函数基础 典型的函数定义包括:返回类型.函数名.由0个或多个形参组成的列表以及函数体. 2.参数传递 形参初始化的机理和变量初始化一样. 有两种方式:引用传递和值传递 2.1 传值参数 当形参是非 ...

  9. Shell中各种括号的作用

    一.小括号,圆括号() 1.单小括号 () ① 命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有分号 ...

  10. python--前端CSS

    一.CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义了如何显示HTML元素,给HTML设置样式,让他更加美观. 当浏览器读到这个样式表, 他就会按照这个样式来对文档进行 ...