zoukankan      html  css  js  c++  java
  • POJ2228 Naptime 环形DP

    题目大意:牛在第i个小时睡觉能够恢复U[i]点体力。睡觉时第一小时不恢复体力。一天的N小时连着下一天的1小时。求能够恢复体力的和的最大值。

    定义DP[i][j][0]为前i个小时休息了j个小时,i小时不休息,DP[i][j][1]为休息。

    如果不考虑N小时连着下一天的1小时,则有递归式:

    DP[i][j][0] = max(DP[i - 1][j][0], DP[i - 1][j][1]);
    if (j > 0)
        DP[i][j][1] = max(DP[i - 1][j - 1][0], DP[i - 1][j - 1][1] + U[i]);

    初值为F[1][0][0](第一小时不睡觉)=DP[1][1][1](第一小时刚开始睡)=0,其余负无穷。终值为max(DP[N][B][0],DP[N][B][1])

    剩下的只有第一小时在熟睡的情况了,只需把初值改为DP[1][1][1]=U[1](一小时在熟睡),终值改为DP[N][B][1](不管N时是在熟睡还是浅睡,必须是在睡觉)。

    两种情况取最大值即可。

    注意:

    • DP时要用滚动数组,否则会超内存
    • 仔细看看初值与终值。
    • 打完代码必须肉眼检查,像把i写成i-1的错误。
    • 共用的innerDP不要两个函数里分别写,有不便于修改等缺点。
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAX_N = 4000, MAX_B = MAX_N;
    int N, B;
    int U[MAX_N];
    int DP[2][MAX_B][2];
    
    void innerDp()
    {
    	for (int i = 2; i <= N; i++)
    	{
    		memset(DP[i & 1], 0xcf, sizeof(DP[i & 1]));
    		for (int j = 0; j <= i; j++)
    		{
    			DP[i & 1][j][0] = max(DP[i - 1 & 1][j][0], DP[i - 1 & 1][j][1]);
    			if (j > 0)
    				DP[i & 1][j][1] = max(DP[i - 1 & 1][j - 1][0], DP[i - 1 & 1][j - 1][1] + U[i]);
    		}
    	}
    }
    
    int DP1()
    {
    	memset(DP, 0xcf, sizeof(DP));
    	DP[1][0][0] = DP[1][1][1] = 0;
    
    	innerDp();
    	return max(DP[N&1][B][0], DP[N&1][B][1]);
    }
    
    
    int DP2()
    {
    	memset(DP, 0xcf, sizeof(DP));
    	DP[1][1][1] = U[1];
    
    	innerDp();
    	return DP[N&1][B][1];
    }
    
    int main()
    {
    #ifdef _DEBUG
    	freopen("c:\noi\source\input.txt", "r", stdin);
    #endif
    	scanf("%d%d", &N, &B);
    	for (int i = 1; i <= N; i++)
    		scanf("%d", i + U);
    	int a = DP1();
    	//printf("%d
    ", a);
    	int b = DP2();
    	//printf("%d
    ", b);
    	printf("%d
    ", max(a, b));
    	return 0;
    }
    

      

  • 相关阅读:
    记第一场省选
    POJ 2083 Fractal 分形
    CodeForces 605A Sorting Railway Cars 思维
    FZU 1896 神奇的魔法数 dp
    FZU 1893 内存管理 模拟
    FZU 1894 志愿者选拔 单调队列
    FZU 1920 Left Mouse Button 简单搜索
    FZU 2086 餐厅点餐
    poj 2299 Ultra-QuickSort 逆序对模版题
    COMP9313 week4a MapReduce
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8545354.html
Copyright © 2011-2022 走看看