1 条题解
-
0
自动搬运
来自洛谷,原作者为

Unknown_Error
OI(2014-2018)搬运于
2025-08-24 22:01:08,当前版本为作者最后更新于2018-05-06 21:45:28,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
我们可以把每个任务所有满足条件的分人方式记录下来。由于人数很少可以用位运算。
按起始时间排序,由于只是改变了原序列对任务分配时的编号,所以用myp标记一下即可。
其实。。。这完全可以暴力
暴力判断是否可行。
真暴力
代码附上:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <vector> using namespace std; #define pb(a) push_back(a) int n,m; int task[20][20]; struct node { int need,val,st,ed,id; }save[100]; long long ans; long long kind[20][2048]; int tim[100],myp[100],sum[100]; void dfs(int now,int val) { if(val>ans) { ans=val; } if(now>m) return ; dfs(now+1,val); bool flag; int tmp[20]; for(int j=1;j<=n;j++) tmp[j]=tim[j]; for(int i=1;i<=kind[myp[now]][0];i++) { flag=true; for(int j=1;j<=n;j++) { if( (kind[myp[now]][i]>>(j-1))&1) { if(tim[j]<save[now].st) { tim[j]=save[now].ed; } else { flag=false; break; } } } if(flag) { dfs(now+1,val+save[now].val); } for(int j=1;j<=n;j++) tim[j]=tmp[j]; } } bool cmp(node aa,node bb) { return aa.st<bb.st; } bool judge(int num) { if(sum[num]==save[num].need) return true; return false; } int main() { int a,b,c; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a); for(int j=1;j<=a;j++) { scanf("%d",&b); task[i][b]=1; } } for(int i=1;i<=m;i++) { scanf("%d%d%d%d",&save[i].st,&save[i].ed,&save[i].need,&save[i].val); save[i].id=i; } int k; for(int i=1;i<=(1<<n)-1;i++) { k=0; for(int j=1;j<=m;j++) sum[j]=0; for(int j=1;j<=n;j++) { if( (i>>(j-1))&1 ) { k++; for(int t=1;t<=m;t++) { if(task[j][t]) { sum[t]++; } } } } for(int j=1;j<=m;j++) { if(judge(j)) { if(sum[j]!=k) continue; kind[j][0]++; kind[j][kind[j][0]]=i; } } } sort(save+1,save+1+m,cmp); for(int i=1;i<=m;i++) { myp[i]=save[i].id; //printf("%d\n",myp[i]); } dfs(1,0); printf("%lld\n",ans); return 0;
- 1
信息
- ID
- 3516
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者