zoukankan      html  css  js  c++  java
  • POJ 1821 Fence

    http://poj.org/problem?id=1821

    题目

    有n块木板排成一行,有k个工人,第$i$个工人坐在第$s_i$块木板处,每刷一块木板的工钱是$p_i$,他只能选择粉刷长度不超过$l_i$,包含$s_i$的连续的一段木板,也可以不粉刷。

    每块木板要么只由一个工人粉刷,要么不粉刷

    问这些工人能得到的工钱的和最大是多少

    $nleqslant16000quad kleqslant100$

    题解

    设dp[i][j]为前i个工人刷了前j块木板

    那么

    $dp[i][j]=dp[i][j-1]$

    $dp[i][j]=dp[i-1][j]$

    $dp[i][j]=max{dp[i-1][k]+(j-k) imes p_i|k<s_i,jgeqslant s_i,j-kleqslant l_i}$

    直接转移,时间复杂度$mathcal{O}(n^2k)$无法接受

    改写一下

    $dp[i][j]=j imes p_i+max{dp[i-1][k]-k imes p_i|j-l_ileqslant k< si}$

    发现max的范围是不断向后移动的,因此可以使用单调队列(滑动窗口)

    那么时间复杂度$mathcal{O}(nk)$

    AC代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<map>
    #define REP(i,a,b) for(register int i=(a); i<(b); i++)
    #define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
    #define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
    using namespace std;
    typedef long long ll;
    int n,m;
    #define MAXN 16007
    #define MAXM 107
    struct node {
    	int l,p,s;
    	bool operator<(const node&r) const {
    		return s<r.s;
    	}
    } a[MAXM];
    int dp[MAXM][MAXN];
    int dw[MAXN], di[MAXN];
    int main() {
    	scanf("%d%d", &n, &m);
    	REP(i,1,m) scanf("%d%d%d", &a[i].l, &a[i].p, &a[i].s);
    	sort(a+1,a+1+m);
    	//dp[i][j] = k<si, j>=si, j-k<=li max(dp[i-1][k]+p*(j-k)) (]
    	//dp[i][j] = j-li<=k<=si max(dp[i-1][k]-p*k)+p*j;
    	//dp[i][j] = dp[i-1][j]
    	//dp[i][j] = dp[i][j-1]
    	memset(dp[0],0,sizeof(dp[0]));
    	REPE(i,1,m) {
    		int l=0,r=0;
    		REP(k,max(a[i].s-a[i].l,0), a[i].s) {
    			int t=dp[i-1][k]-a[i].p*k;
    			while(r>l && dw[r-1]<t) r--;
    			dw[r]=t;
    			di[r]=k;
    			r++;
    		}
    //]		int mj=min(a[i].l+a[i].s, n);____
    		dp[i][0]=0;
    		REPE(j,1,n) {
    			dp[i][j]=max(dp[i][j-1], dp[i-1][j]);
    			if(j>=a[i].s) {
    				int t=j-a[i].l; while(l<r && di[l]<t) l++;
    				if(l<r) dp[i][j]=max(dp[i][j], dw[l]+a[i].p*j);
    			}
    		}
    	}
    	printf("%d
    ", dp[m][n]);
    }
    
  • 相关阅读:
    PowerDesigner将PDM导出生成WORD文档
    哨兵机制
    redis 主从数据同步
    redis RDB
    redis AOF机制
    redis数据结构
    dependencyManagement 和 dependencies的区别
    同源策略 跨域资源共享
    高可用 可扩展 多层反向代理架构演进
    String 杂记
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12551492.html
Copyright © 2011-2022 走看看