Atribuição de tarefas (dp)

Atribuição de tarefas (dp)

Descrição

Existem n tarefas a serem concluídas por A e B. Cada tarefa é concluída por A ou B, e o tempo necessário é ai e bi, respectivamente. Pergunte quanto tempo levará para concluir todas as tarefas, pelo menos.

Entrada

Um número inteiro positivo nn na primeira linha indica que há n tarefas.
Em seguida, existem n linhas, cada uma com dois inteiros positivos ai e bi.

Resultado

Um número, o tempo mínimo de que precisam para concluir todas as tarefas.

Amostras

Entrada

3
5 10
6 11
7 12

Resultado

12

Dica

[Explicação das amostras de entrada e saída]
A conclui a tarefa 1 e a tarefa 2 e o tempo é 11. B conclui a tarefa 3 às 12h.
Ou A conclui a tarefa 1 e a tarefa 3, o tempo é 12. B conclui a tarefa 2 no tempo 11.
[Limites]
30% dos dados atendem: 1≤n≤20
100% dos dados atendem: 1≤n≤200, 1≤ai, bi≤200

Ideias:

Dp tridimensional é melhor empurrar, mas o tempo e o espaço não permitem isso.

A solução positiva é um estado dp bastante estranho.

dp [i] [j] significa completar as primeiras i tarefas, e o tempo gasto por A é j;

O valor de dp [i] [j] representa o tempo que leva para B completar as primeiras i tarefas.

A divisão é baseada em se a i-ésima tarefa é concluída por A ou B.

Código:

const int maxn=210;
int dp[maxn][maxn*maxn];
int a[maxn],b[maxn],n;
void solve(){
	n=read();
	for(int i=1;i<=n;i++){
		a[i]=read(),b[i]=read();
	}
	memset(dp,0x3f,sizeof dp);
	dp[0][0]=0;
	int sum=0;
	for(int i=1;i<=n;i++){
		sum=sum+a[i];
		for(int j=0;j<=sum;j++){
			dp[i][j]=dp[i-1][j]+b[i];//b完成第i个任务 
			if(j>=a[i]) dp[i][j]=min(dp[i][j],dp[i-1][j-a[i]]);//a完成第i个任务 
		}
	}
	int res=0x3f3f3f3f;
	for(int i=0;i<=sum;i++)///可能需要的时间 
		res=min(res,max(i,dp[n][i]));///注意取的先后顺序 
	cout<<res<<endl;
}

referência

Acho que você gosta

Origin blog.csdn.net/weixin_45675097/article/details/113594909
Recomendado
Clasificación