目錄
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;
}