题目:https://loj.ac/problem/2557

第一个点可以暴搜。

第三个点无依赖关系,k=3,可以 DP 。dp[ cr ][ i ][ j ] 表示前 cr 个任务、第一台机器最晚完成时间是 i 、第二台机器最晚完成时间是 j ,第三台机器最晚完成时间是多少。数组开 500 就行了。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
const int N=55,M=505,K=5,INF=1e9+5;
int n,m,k,op,dp[N][M][M],pr[N][M][M][2];
int t[N][K],r[K][K],prn[N];
int main()
{
  scanf("%d%d%d%d",&n,&m,&k,&op);
  for(int i=1;i<=n;i++)
    for(int j=1;j<=k;j++)
      scanf("%d",&t[i][j]);
  for(int i=1;i<=k;i++)
    for(int j=1;j<=k;j++)
      scanf("%d",&r[i][j]);
  memset(dp,0x3f,sizeof dp);
  dp[0][0][0]=0;
  for(int cr=1;cr<=n;cr++)
    for(int i=0;i<=500;i++)
      for(int j=0;j<=500;j++)
    {
      int w=t[cr][3];
      dp[cr][i][j]=dp[cr-1][i][j]+w;
      pr[cr][i][j][0]=i; pr[cr][i][j][1]=j;
      w=t[cr][1];
      if(i>=w&&dp[cr-1][i-w][j]<dp[cr][i][j])
        {
          dp[cr][i][j]=dp[cr-1][i-w][j];
          pr[cr][i][j][0]=i-w; pr[cr][i][j][1]=j;
        }
      w=t[cr][2];
      if(j>=w&&dp[cr-1][i][j-w]<dp[cr][i][j])
        {
          dp[cr][i][j]=dp[cr-1][i][j-w];
          pr[cr][i][j][0]=i; pr[cr][i][j][1]=j-w;
        }
    }
  int ans=INF,r0,r1;
  for(int i=0;i<=500;i++)
    for(int j=0;j<=500;j++)
      {
    int d=Mx(Mx(i,j),dp[n][i][j]);
    if(d<ans)ans=d,r0=i,r1=j;
      }
  for(int i=n;i;i--)
    {
      int t0=pr[i][r0][r1][0],t1=pr[i][r0][r1][1];
      if(t0!=r0)prn[i]=1; else if(t1!=r1)prn[i]=2; else prn[i]=3;
      r0=t0; r1=t1;
    }
  for(int i=1;i<=n;i++)printf("%d ",prn[i]);puts("");
  return 0;
}
View Code

相关文章:

  • 2022-03-04
  • 2021-06-09
  • 2021-11-24
  • 2022-12-23
  • 2021-05-19
  • 2021-06-11
猜你喜欢
  • 2022-03-08
  • 2021-09-09
  • 2021-08-17
  • 2022-12-23
  • 2021-06-30
  • 2022-12-23
  • 2021-06-03
相关资源
相似解决方案