poj 1821 动态规划

思路:每次枚举每个工人的右边界j,维护最优的左边界k。那么dp[j]=max(dp[j],dp[k]+(j-k)*w[i].p);

对于每个工人的初值k=w[i].s-1;

令x=j-w[i].l,如果(k-x)*w[i].p>dp[k]-dp[x],则k=x。

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define Maxn 170010
#define Maxm 200010
#define LL __int64
#define Abs(x) ((x)>0?(x):(-x))
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define inf 100000
#define lowbit(x) (x&(-x))
#define clr(x,y) memset(x,y,sizeof(x))
#define Mod 1000000007
using namespace std;
int dp[Maxn];
struct Workers{
    int s,p,l;
    int operator<(const Workers &temp) const{
        return s<temp.s;
    }
}w[110];
int main()
{
    int n,i,j,K,k,x;
    //freopen("aa.txt","r",stdin);
    while(scanf("%d%d",&n,&K)!=EOF){
        clr(dp,0);
        for(i=1;i<=K;i++){
            scanf("%d%d%d",&w[i].l,&w[i].p,&w[i].s);
        }
        sort(w+1,w+1+K);
        int ed,st,temp;
        for(i=1;i<=K;i++){
            int ed=w[i].s+w[i].l-1;
            k=w[i].s-1;
            for(j=ed;j>=w[i].s;j--){
                x=j-w[i].l;
                x=max(x,0);
                if((k-x)*w[i].p>dp[k]-dp[x])
                    k=x;
                dp[j]=max(dp[j],dp[k]+(j-k)*w[i].p);
            }
            for(j=1;j<=n;j++)
            dp[j]=max(dp[j],dp[j-1]);
        }
        printf("%d
",dp[n]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wangfang20/p/3338646.html