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\n",dp[n]);

    }

    return 0;

}

 

你可能感兴趣的:(动态规划)