题目:圆桌问题
思路:
贪心,优先考虑人数多的团体,优先放在人数多的桌子上。
如果不嫌麻烦考虑网络流做法,只需把起点和所有团体连人数的边,团体和桌子连1,桌子和汇点连容量边跑最大流就好。
美丽的贪心代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 300
#define read(x) scanf("%d",&x)
struct Pair{
int x,y;
Pair(){}
Pair(int xx,int yy) {x=xx,y=yy;}
bool operator < (const Pair& oth) const {return x<oth.x;}
};
int n,m;
int a[maxn+5],b[maxn+5];
Pair c[maxn+5];
int d[maxn+5];
Pair e[maxn+5];
int f[maxn+5];
int g[maxn+5][maxn+5];
int main() {
read(n),read(m);
for(int i=1;i<=n;i++) read(a[i]),c[i]=Pair(a[i],i);
for(int i=1;i<=m;i++) read(b[i]),e[i]=Pair(b[i],i);
sort(c+1,c+n+1);
sort(e+1,e+m+1);
for(int i=1;i<=n;i++) {
d[c[i].y]=i;
}
for(int i=1;i<=m;i++) {
f[e[i].y]=i;
}
for(int i=n;i>=1;i--) {
int t=0;
for(int j=m;j>=1&&t<c[i].x;j--) {
if(e[j].x) e[j].x--,t++,g[i][t]=j;
}
if(t<c[i].x) {printf("0");return 0;}
}
printf("1\n");
for(int i=1;i<=n;i++) {
for(int j=a[i];j>=1;j--) printf("%d ",e[g[d[i]][j]].y);
printf("\n");
}
return 0;
}