가로등 을 끄다
컨텐트는 다음과 같습니다.
이것은 구간형의 동적 기획 문제이다.
나는 주로 전방의 몇몇 dp문제에 대해 약간의 세부 사항을 보충한다.
기왕 동규라면 먼저 자주 사용하는 작성법과 브러쉬법에 대해 이야기하자.
메모법은 상태 전이 방정식과 이전 상태를 이용하여 나타난 상태를 유도하는 것이다(이미 알고 있는 조건을 알고 답안을 채우는 것과 같다)
브러시법은 현재의 상태를 이용하여 관련된 다음 상태를 모두 밀어내는 것이다.
이 문제는 내가 선택한 것이 기입법이다.
제목의 대의를 이해하다.
불을 끄는 데는 별도의 시간이 필요 없고, 불이 지나가면 꺼진다.하지만 되돌아가서 큰 불을 끄는 것이 아래로 내려가서 끄는 것보다 더 좋을 수도 있고,
그러면 두 가지 상태를 얻을 수 있다.
우리가 필요로 하는 전체 전등 과정 중의 최우수치(최소 에너지 소모)
그러면 설계해야 할 상태 이동 방정식에는 틀림없이 두 가지 방안이 있을 것이다(되돌아오는, 벽에 부딪히지 않고 돌아오지 않는)
또한 특정 구간의 불을 끄는 과정에서 에너지 소모가 가장 적기 때문에 하나의 구간으로 바꾸어 쓸 수 있다.
어떤 구간의 불을 끄면 거리 전체가 이 구간의 불을 제외하고는 점차 꺼질 것이고 다른 것은 틀림없이 모두 밝을 것이다.
그러면 우리는 f[i][j]를 i에서 j까지의 불이 모두 꺼진 후에 남은 불의 총 출력으로 기억한다.
한 걸음 더: f[i][j][0]는 i에서 j까지의 불을 끄면 라오쟝은 i점에 서고, f[i][j][1]는 [i][j]의 불을 끄면 라오쟝은 오른쪽 끝에 서고
(i는 왼쪽 끝, j는 오른쪽 끝)
또 f[i][j][0]는 두 가지 방안에서 유도된다(위에 쓰여 있다.):되돌아와서 i, j의 등불을 끄고 i+1에서 깊이 들어가 i개의 등불을 계속 끄고 (i, j)까지 확장한다.
그래서 상태 이동 방정식을 얻는다.
f[i][j][0] = min ( f[i+1][j][0] + ( a[i+1] - a[i] ) * ( sum[i] + sum[n] - sum[j] ) , f[i+1][j][1] + ( a[j]-a[i] ) * ( sum[i]+sum[n]-sum[j]) );
f[i][j][1] = min ( f[i][j-1][0] + ( a[j] - a[i] ) * ( sum[i-1] + sum[n] - sum[j-1] ) , f[i][j-1][1] + ( a[j]-a[j-1] ) * ( sum[i-1] + sum[n] - sum[j-1] ) );
(지금의 가로등 l(2-n, c위의 가로등이 꺼졌기 때문), i+l-1<=n(길은 이렇게 길다), j=i+l-1(오른쪽 끝))
왜냐하면 마지막에 장씨가 왼쪽 단점이 가장 좋은지 오른쪽 단점이 가장 좋은지 몰랐거든요.
그래서 f[1][n][0]와 f[1][n][1]에서min 출력을 얻는다.
코드 첨부(설명 포함)
#include
#include
using namespace std;
const int MAXM=60;
int a[MAXM],b[MAXM],sum[MAXM],n,m,c;
int f[MAXM][MAXM][2];
int min(int a,int b)// : max min ,
{return aint max(int a,int b)
{return a>b?a:b;}
int main()
{
scanf("%d%d",&n,&c);
memset(f,127,sizeof(f));// min
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i],&b[i]),sum[i]=sum[i-1]+b[i];
f[c][c][0]=f[c][c][1]=0;// ( )
for(int l=2;l<=n;l++)
for(int i=1;i+l-1<=n;i++)
{
int j=i+l-1;
f[i][j][0]=min(f[i+1][j][0]+(a[i+1]-a[i])*(sum[i]+sum[n]-sum[j]),// ?
f[i+1][j][1]+(a[j]-a[i])*(sum[i]+sum[n]-sum[j]));// j ?( [i+1][j] ,i , j i)
// sum[n]-(sum[j]-sum[i]) i , i
f[i][j][1]=min(f[i][j-1][0]+(a[j]-a[i])*(sum[i-1]+sum[n]-sum[j-1]),//
f[i][j-1][1]+(a[j]-a[j-1])*(sum[i-1]+sum[n]-sum[j-1]));
}
int ans=min(f[1][n][0],f[1][n][1]);
printf("%d",ans);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
제11회 산동성 대학생 프로그램 설계 경연대회 Adventurer's Guild(dp)전송문 제목: 몬스터의 수량 n, 캐릭터의 생명력 H, 캐릭터의 공격 S 건네기;다음 n행, 매 행위 매 몬스터의 혈액량 h, 공격 s, 가치 w; 매번 몬스터를 처치할 때마다 h의 혈액량과 s의 공격을 소모한다. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.