[로곡 P1280] 닉의 의뢰

2628 단어 동적 기획
비교적 색다른 DP가 처음에는 생각해 내지 못했는데 DP를 사용하지 않아도 나올 수 있을 것 같아서 문제풀이를 보니 이렇게 간단했구나.
dp[i]는 i에서 시작하는 최대 여가 시간을 표시하고 dp를 역순으로 밀어낸다.
상황별:
1: 만약 시간을 변경하여 일을 시작해야 하지 않는다면 당연히 쉬어야 한다. 지금 1분 쉰다는 뜻이다. dp[i]=dp[i+1]+1
2: 만약에 시작해야 할 일이 있다면 모든 시작해야 할 일 중에서 가장 좋은 것을 골라라. dp[그들의 마지막 시간 +1]가 가장 큰 것은 그들이 일을 끝낸 후에 최대 얼마나 쉴 수 있는지를 나타낸다. (마침 일을 끝낸 1분, 즉 일의 마지막 1분, 휴식이 아니다) 이것이 바로 +1의 원인이다. 왜?우리는 모든 임무에 대해 만약 내가 이 임무를 한다면 얻을 수 있는 최대 여가 시간은 얼마입니까?그냥 작업하고 나서 가장 여유로운 시간이죠.
그런데 거꾸로 밀어야 하는 이유가 뭔지 생각해봐.정방향으로 밀면 앞의 선택이 뒤의 선택에 영향을 주고 기록할 방법이 없다.
DP를 왜 역순으로 돌려요?선택은 임무의 시작이지 임무의 끝이 아니기 때문에 같은 시점에서 상태를 옮기려면 반드시 뒤에서 앞으로 나아가야 하기 때문에 이 방법이 있다.
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using namespace std;
int begin[100005],end[100005],f[100005],N,K;
int main(){
   //freopen("std.in","r",stdin);
    scanf("%d%d",&N,&K);
    for(int i=1;i<=K;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        begin[i]=a;end[i]=b;
    }
    int point=K;
    for(int i=N;i>=1;i--){
        if(begin[point]!=i) f[i]=f[i+1]+1;
        else{
            while(i==begin[point]){
                f[i]=max(f[i],f[i+end[point]]);
                point--;
            }
        }
    }
    printf("%d
"
,f[1]); return 0; }

좋은 웹페이지 즐겨찾기