[알고리즘 입문] 단조로운 대기열 최적화 동적 기획: [RomaniaOI2002]Fence
16960 단어 DP 동적 계획
Description A team of k (1 <= K <= 100) workers should paint a fence which contains N (1 <= N <= 16 000) planks numbered from 1 to N from left to right. Each worker i (1 <= i <= K) should sit in front of the plank Si and he may paint only a compact interval (this means that the planks from the interval should be consecutive). This interval should contain the Si plank. Also a worker should not paint more than Li planks and for each painted plank he should receive Pi $ (1 <= Pi <= 10 000). A plank should be painted by no more than one worker. All the numbers Si should be distinct. Being the team’s leader you want to determine for each worker the interval that he should paint, knowing that the total income should be maximal. The total income represents the sum of the workers personal income. Write a program that determines the total maximal income obtained by the K workers. Input The input contains: Input N K L1 P1 S1 L2 P2 S2 … LK PK SK Semnification N -the number of the planks; K ? the number of the workers Li -the maximal number of planks that can be painted by worker i Pi -the sum received by worker i for a painted plank Si -the plank in front of which sits the worker i Output The output contains a single integer, the total maximal income. Sample Input 8 4 3 2 2 3 2 3 3 3 5 1 1 7 Sample Output 17
Solution
#include
#include
#include
#include
using namespace std;
struct node{int l,p,s;};
node a[200];
int N,K,t,h;
int L[200],P[200],S[200],f[200][50000],q[50000];
inline bool cmp(node a,node b)
{
if (a.s<b.s) return true;
return false;
}
#define val(i,k) (f[i-1][k]-k*P[i])
int main(void)
{
cin>>N>>K;
for (int i=1;i<=K;++i)
cin>>a[i].l>>a[i].p>>a[i].s;
sort(a+1,a+K+1,cmp);
// si
for (int i=1;i<=K;++i)
L[i]=a[i].l,P[i]=a[i].p,S[i]=a[i].s;
//
for (int i=1;i<=K;++i)
{
for (int j=max(0,S[i]-L[i]);j<=S[i]-1;++j)
{
while (h<=t && val(i,j)>=val(i,q[t])) --t;
q[++t]=j;
}
//
for (int j=1;j<=N;++j)
{
f[i][j]=max(f[i-1][j],f[i][j-1]);
// 1,2
if (j<S[i]) continue;
while (h<=t && q[h]<j-L[i]) h++;
//
if (h<=t) f[i][j]=max(f[i][j],f[i-1][q[h]]+(j-q[h])*P[i]);
// 3
}
}
cout<<f[K][N]<<endl;
return 0;
}
마지막으로 단조로운 대기열 최적화 상황을 정리했다. 상태 이동 방정식은 다음과 같다. f[i]=m in(f[j]+v al(i, j), L(i)≤j≤R(i) f[i]=min(f[j]+val(i, j), L(i)≤j≤R(i) f[i]=min(f[j]+val(i, j), L(i)≤jj≤R(i) 중 상하계의 변화가 있다.다항식 v a l (i, j) val (i, j) val (i, j) 의 모든 단항식은 i i 개 j j 중의 한 항목만 관련될 수 있고 i i 와 j j의 곱셈 항목을 동시에 포함할 수 없습니다.이것이 바로 단조로운 대열 최적화다.본문에 만약 누락되거나 잘못된 점이 있으면 독자의 지적을 환영합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
01 가방 문제(DP 동적 계획)n개의 무게와 가치가 각각 와이,vi인 물품이 있습니다.이 물품들 중에서 총 중량이 W를 초과하지 않는 물품을 골라 모든 선택 방안 중 가치 총화의 최대치를 구한다. 1<=n<=100 1<=wi,vi<=100 1<=...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.