洛谷P1280 尼克的任务

题目链接

P1280 尼克的任务

解题思路

动态规划,这几天断断续续想了这个题,难点在于递推关系式的构造。
顺着更新的话,第 i i i个时刻需要知道第 i + 1 i+1 i+1时刻的值,这显然是不太方便的,所以这里记 f [ i ] f[i] f[i]为第 i i i个时刻到第 n n n个时刻的值,逆着更新。其中 b [ i ] b[i] b[i]为以第 i i i个时刻为起点的所有时间段的统计。
f [ i ] = f [ i + 1 ] + 1 b [ i ] = 0 f[i]=f[i+1]+1 \quad b[i]=0 f[i]=f[i+1]+1b[i]=0
f [ i ] = m a x ( f [ i ] , f [ i + a [ c n t ] . t ] ) b [ i ] ≠ 0 f[i]=max(f[i],f[i+a[cnt].t]) \quad b[i]\ne 0 f[i]=max(f[i],f[i+a[cnt].t])b[i]̸=0
由于为 a [ i ] . p a[i].p a[i].p逆序排列,所以可以用 c n t cnt cnt来判断第 i i i个时刻为起点的持续时间。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int mx=10010;
//f[i]=f[i+1]+1
//f[i]=f[i+t]
struct node{
    int p,t;
}a[mx];
bool cmp(node a,node b){
    return a.p>b.p;//降序 
}
int f[mx],b[mx],cnt=1;
int main(int argc, char** argv) {
    int N,K;
    scanf("%d%d",&N,&K);
    for(int i=1;i<=K;i++)  {
        scanf("%d%d",&a[i].p,&a[i].t);
        b[a[i].p]++;//储存相同时间起点 
    }
    sort(a+1,a+K+1,cmp);
    
//	for(int i=1;i<=K;i++){
//		printf("%d %d\n",a[i].p,a[i].t);
//	}
    for(int i=N;i>=1;i--){//倒数第二个时间开始 
        if(!b[i])  f[i]=f[i+1]+1;
        else{
            for(int j=1;j<=b[i];j++){
                f[i]=max(f[i],f[i+a[cnt].t]);
                cnt++;
            }
        } 
    }
    printf("%d\n",f[1]);
    return 0;
}
posted @ 2018-09-29 22:07  xzhws  阅读(37)  评论(0编辑  收藏  举报