poj1821 Fence
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.
dp [i] [j] 를 설정 하면 앞의 i 명의 노동자 가 앞의 j 면 벽 을 닦 는 것 을 나타 낸다.소박 한 dp 방정식 을 고려 하여 dp [i] [j] = max {dp [i - 1] [j], dp [i] [j - 1], dp [i - 1] [k] + p [i] * (j - k) | (j > = s [i] & j < = s [i] + l [i] - 1 & j - k + 1 & l [i] & k < s [i])}.[각자 의 의 미 는 다음 과 같다. i 번 째 사람 은 칠 하지 않 고 j 번 째 벽 은 칠 하지 않 으 며 i 번 째 사람 은 k + 1. j 의 벽 을 칠 한다.] 그러나 주의해 라. 이 방정식 의 응용 조건 은 dp [i - 1] [k] 이미 계산 했다. [더 정확 한 것 은 이곳 에 칠 할 수 있 는 사람 은 모두 칠 했다 는 것 이다.]그리고 쉽게 알 수 있 듯 이 s 는 왼쪽 에 있 고 마지막 에 칠 한 구역 은 반드시 왼쪽 에 있 으 며 교차 하 는 상황 이 발생 하지 않 습 니 다.그래서 먼저 s 에 따라 정렬 하고 순서대로 dp 를 해 야 합 니 다.앞의 두 개 는 모두 O (1) 로 옮 길 수 있 지만 세 번 째 이전 은 O (m) 가 필요 하 다.dp [i - 1] [k] + p [i] * (j - k) = p [i] * j + dp [i - 1] [k] - p [i] * k 기 f (k) = dp [i - 1] [k] - p [i] * k.원 식 = p [i] * j + f (k).이 식 은 앞의 항목 은 k 와 무관 하 며, 뒤의 항목 은 i 가 확 정 된 상황 에서 k 와 만 관련 이 있 으 며, j 가 증가 함 에 따라 k 의 상계 가 변 하지 않 고 하계 가 증가 하기 때문에 단조 로 운 대기 열 로 최적화 할 수 있 습 니 다.구체 적 인 방법 은 i 가 확 정 될 때마다 k 가 증가 하고 f (k) 가 감소 하 는 단조 로 운 대기 열 을 유지 하 는 것 입 니 다.그러나 이 단조 로 운 대기 열 은 '최대 하위 순서 와' [여기 참조] 와 달리 k 의 상 계 는 j 의 증가 에 따라 증가 하 는 것 이 아니 라 변 하지 않 는 다.따라서 입단 작업 은 j 에 따라 진행 되 는 것 이 아니 라 처음부터 모두 입단 한 다음 에 j 가 증가 함 에 따라 팀 을 나 가 야 한다.
#include
#include
#include
using namespace std;
int max(int x,int y)
{
return x>y?x:y;
}
struct worker
{
int l,p,s;
bool operator < (const worker &a) const
{
return s110];
int dp[110][16010],que[16010];
int fun(int i,int k)
{
return dp[i-1][k]-a[i].p*k;
}
int main()
{
int i,j,k,m,n,q,x,y,z,hd,tl;
scanf("%d%d",&m,&n);
for (i=1;i<=n;i++)
scanf("%d%d%d",&a[i].l,&a[i].p,&a[i].s);
sort(a+1,a+n+1);
for (i=1;i<=n;i++)
{
hd=1;
tl=0;
for (j=0;j<=a[i].s-1;j++)
{
while (hd<=tl&&fun(i,que[tl])<=fun(i,j)) tl--;
que[++tl]=j;
}
for (j=1;j<=m;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if (j>=a[i].s&&j<=a[i].s+a[i].l-1)
{
while (hd<=tl&&j-que[hd]>a[i].l) hd++;
if (hd<=tl)
dp[i][j]=max(dp[i][j],a[i].p*j+fun(i,que[hd]));
}
}
}
printf("%d
",dp[n][m]);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
124. 두 갈래 나무의 최대 경로와 leetcode비공 두 갈래 트리를 지정하고 최대 경로와 를 되돌려줍니다. 본고에서 경로는 나무의 임의의 노드에서 출발하여 임의의 노드에 도달하는 서열로 정의되었다.이 경로는 루트 노드를 거치지 않고 하나 이상의 노드를 포함합니다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.