2024/11/30课堂记录
目录
1. 机器分配
2.最大食物链计数
3.菜肴制作
多重背包变式,改变一下计算价值的方式
另外,题目里没提到要前面的公司尽量少分配,后面的公司尽量多分配,不然90分
所以比较时要<=(20行)
见代码,写注释了
点击查看代码
#include<iostream>
using namespace std;
int a[20][20],f[20][20],b[20][20];
void out(int n,int m)
{
if(n==0) return;
out(n-1,m-b[n][m]);//先输出前面的,前面要用n-1个公司分 m-b[n][m]台机器
cout<<n<<" "<<b[n][m]<<"\n";
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)//第i家到来
for(int j=1;j<=m;j++)//只给i以前的j台机器
for(int k=0;k<=j;k++)//可以不分配,从0开始,不能超过j
if(f[i][j]<=f[i-1][j-k]+a[i][k])//满足隐藏条件
f[i][j]=f[i-1][j-k]+a[i][k],b[i][j]=k;//总工j台,前面i-1家给j-k台,第i家给k台
cout<<f[n][m]<<"\n";
out(n,m);
return 0;
}
很经典的一道链式前向星+拓扑
理解难度不大,不开longlong见祖宗
点击查看代码
#include<iostream>
using namespace std;
int r[5050],c[5050];//入度出度
long long int f[5050];//每个点之后最大值 ,不开longlong见祖宗
int stack[5050],top;//借助栈,top指向最高存储格
long long int sum;//不开longlong见祖宗
//以下为链式前向星标准模版
struct EDGE
{
int next,to;
}edge[500500];
int head[5050],tot;
void add(int from,int to)
{
edge[++tot].next=head[from];
edge[tot].to=to;
head[from]=tot;
}
//以上为链式前向星标准模版
int main()
{
int n,m;
cin>>n>>m;
while(m--)
{
int a,b;
cin>>a>>b;
add(b,a);//反向建图,与生物学相反,吃->被吃
c[b]++;
r[a]++;
}
for(int i=1;i<=n;i++)
if(r[i]==0)//最高级消费者
stack[++top]=i,f[i]=1;//入栈,代表一个终点
while(top)
{
int from=stack[top--];
for(int i=head[from];i;i=edge[i].next)
{
int to=edge[i].to;
f[to]+=f[from]%80112002;//累计方案数
r[to]--;//删边
if(r[to]==0)//变成了最高级消费者
{
stack[++top]=to;//入栈
if(c[to]==0)//如果又是生产者
sum+=f[to]%80112002;//累计答案
}
}
}
cout<<sum%80112002;
return 0;
}
链式前向星,反向建图,拓扑,反向存储输出,理解难度大,优先队列
暂时没完全看懂,但看懂收获一定很大
点击查看代码
//https://www.luogu.com.cn/problem/solution/P3243
//菜肴制作-拓扑排序3
//反向建图+最大字典序
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#define ll long long
#define INF 0x7fffffff
using namespace std;
priority_queue<int>que; //默认大根堆
int t,n,m,x,cnt,d[100005],k[100005],ans[100005];
struct Edge
{
int to,next;
}edge[100005];
struct node{
int x,y;
}u[100005];
void add(int x,int y)
{
edge[++cnt].to = y;
edge[cnt].next = d[x];
d[x] = cnt;
k[y] ++;
}
/*
int mysort(node a,node b)
{
return a.y < b.y;
}
*/
void clean()
{
while(!que.empty())
que.pop();
}
void work()
{
for(int i = 1; i <= n; i++)
if(k[i] == 0)
que.push(i);
while(!que.empty())
{
x = que.top();
ans[++cnt] = x;
que.pop();
for(int i = d[x]; edge[i].to != 0; i = edge[i].next)
{
k[edge[i].to] --;
if(k[edge[i].to] == 0)
que.push(edge[i].to);
}
}
}
int main()
{
scanf("%d",&t);
for(int a = 1; a <= t; a++)
{
cnt = 0;
memset(d,0,sizeof(d));
memset(k,0,sizeof(k));
clean();
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++)
scanf("%d%d",&u[i].x,&u[i].y);
for(int i = 1; i <= m; i++)
add(u[i].y,u[i].x);
cnt = 0;
work();
if(cnt < n)
printf("Impossible!");
else
for(int i = n; i >= 1; i--)
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}