P1280 尼克的任务(线性dp)

P1280 尼克的任务(线性dp)

思路:线性 d p dp ,从后往前考虑,设 d p [ i ] dp[i] 表示从 i n i\sim n 的最大空闲时间。

若当前实际 i i 无任务, d p [ i ] = d p [ i + 1 ] + 1 dp[i]=dp[i+1]+1 .

否则 d p [ i ] = m a x ( d p [ i + a [ j ] . t i m e ] ) , a [ j ] . t i m e dp[i]=max(dp[i+a[j].time]),a[j].time表示任务的持续时间

这样满足无后效性。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
inline void read(int &x){ 
	x=0;int w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
	for(;ch>='0'&&ch<='9';ch=getchar())
		x=(x<<3)+(x<<1)+(ch&15);
	x*=w; 
}
bool cmp(PII a,PII b){
	return a.fi>b.fi;
} 
int n,k,id=1,dp[N],cnt[N];
PII a[N];
int main(){
	read(n),read(k);
	for(reg int i=1;i<=k;i++) read(a[i].fi),read(a[i].se),cnt[a[i].fi]++;
	sort(a+1,a+k+1,cmp);
	for(reg int i=n;i>=1;i--){
		 if(!cnt[i]) dp[i]=dp[i+1]+1;
		 else for(int j=1;j<=cnt[i];j++,id++)
		 			if(dp[i+a[id].se]>dp[i]) dp[i]=dp[i+a[id].se];
	}
	printf("%d\n",dp[1]);
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/106626137
今日推荐