hdu3507 경사율 최적화 dp
이 문제의 동적 기획 방정식을 주의하십시오: dp[i]=max(dp[j]+(sum[i]-sum[j])^2+m;
간략화: dp[i]=max(dp[j]+sum[i]^2+sum[j]^2-2*sum[i]*sum[j]);단조로운 대기열로 직접 최적화할 수 없습니다. i와 j는 분리할 수 없습니다.
가령 j가 k보다 낫다고 가정하다
dp[j]+sum[i]^2+sum[j]^2-2*sum[i]*sum[j]
dp[j]+sum[j]^2-(dp[k]+sum[k]^2)/(2*dp[j]-2*dp[k])
여기에는 두 가지 결론이 쓰인다.
1.g[j,k]
g[i, j]
주의 사항:
1. 여기서sum[i]는 점차적으로 증가하고 g[j,k](사율)도 점차적으로 증가하기 때문에 매번 사율이sum[i]보다 큰 점을 만족시키지 못하면 이후에도 어떤sum[i]보다 크지 않기 때문에 팀을 나가야 한다.dp[i]를 계산할 때 팀의 우두머리에서 가장 좋은 것을 찾는다. 즉, g[q[head+1], q[head]<=sum[i]의 점을 만족시키지 못하는 것이다. 즉, 사율이 sum[i]보다 큰 점을 찾고 sum[i]보다 작거나 같은 점을 찾아낸다.같은 경우도 안 된다.
2. 매번 입대할 때마다 경사율의 단조로운 증가성을 확보해야 한다.i입대, g[i,j]>g[j,k];
다음은 코드입니다.
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<cstdio>
#include<cstring>
#define maxn 500005
#define INF 0xfffffff
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
using namespace std;
int n,m,head,tail;
int sum[maxn],q[maxn],dp[maxn];
int getUp(int i,int j)
{
return dp[i]+sum[i]*sum[i]-dp[j]-sum[j]*sum[j];
}
int getDown(int i,int j)
{
return 2*sum[i]-2*sum[j];
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
sum[0]=dp[0]=0;// 0
for(int i=1;i<=n;i++)
{
scanf("%d",&sum[i]);
sum[i]=sum[i-1]+sum[i];
}
head=tail=0;
q[tail++]=0;// 0 , 2
for(int i=1;i<=n;i++)
{
while(head+1<tail&&getUp(q[head+1],q[head])<=sum[i]*getDown(q[head+1],q[head]))// g[j,k]<=sum[i]
head++;
dp[i]=dp[q[head]]+m+(sum[i]-sum[q[head]])*(sum[i]-sum[q[head]]);
while(head+1<tail&&getUp(i,q[tail-1])*getDown(q[tail-1],q[tail-2])<=getUp(q[tail-1],q[tail-2])*getDown(i,q[tail-1]))// g[i,j]<=g[j,k]
tail--;
q[tail++]=i;
}
printf("%d
",dp[n]);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.