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;
}
posted @ 2024-11-30 21:42  永韶  阅读(3)  评论(0编辑  收藏  举报