• 洛谷P1280 && caioj 1085 动态规划入门(非常规DP9:尼克的任务)


    这道题我一直按照往常的思路想
    f[i]为前i个任务的最大空暇时间
    然后想不出来怎么做……
    后来看了题解
    发现这里设的状态是时间,不是任务
    自己思维还是太局限了,题做得太少。

    很多网上题解都反着做,那么麻烦干嘛

    设f[i]为前i时间内的最大空暇时间。
    这里是更新后来的状态,和以前不一样。
    如果i为某个任务的开始时间,则
    f[i+t-1] = max(f[i+t-1], f[i])
    也就是继承过去,取max
    如果不是的话
    f[i] = max(f[i], f[i-1] + 1)
    加上获得的空暇时间
    最后输出f[time],time为总时间

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    const int MAXN = 11234;
    int f[MAXN], time, n;
    struct node
    {
    	int l, r;
    	bool operator < (const node& rhs) const
    	{
    		return l < rhs.l || (l == rhs.l && r < rhs.r); 
    	}
    }a[MAXN];
    
    int main()
    {
    	scanf("%d%d", &time, &n);
    	REP(i, 1, n + 1) scanf("%d%d", &a[i].l, &a[i].r);
    	sort(a + 1, a + n + 1);
    	
    	memset(f, -63, sizeof(f));
    	f[0] = 0;
    	int p = 1;
    	REP(i, 1, time + 1)
    	{
    		if(a[p].l == i)
    		{
    			while(a[p].l == i)
    				f[i + a[p].r - 1] = max(f[i + a[p].r - 1], f[i-1]), p++;
    		}
    		else f[i] = max(f[i], f[i-1] + 1);
    	}
    	printf("%d
    ", f[time]);
    	
    	return 0;
    }

    后来做到洛谷P1280,竟然做不出来了,看来对题解还是没有深刻的理解
    (1)初始化问题。本来以为全部都是0无所谓的,然后就WA。
    因为求最大,所以初始化为最小,同时f[0] = 0
    (2)这里推时间是从f[i-1]推,不是f[i]

    然后我发现把这个f数组输出来乱七八糟的。
    但是答案是对的
    有点迷(因为下标是时间??)

    最后,这11天过来我的代码风格还是有少许改变的

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    #define _for(i, a, b) for(int i = (a); i <= (b); i++)
    using namespace std;
    
    const int MAXN = 112345;
    int f[MAXN], n, k;
    struct node 
    { 
    	int l, r;
    	void read() { scanf("%d%d", &l, &r); r = l + r - 1; }
    	bool operator < (const node& rhs) const
    	{
    		return l < rhs.l || (l == rhs.l && r < rhs.r);
    	}
    }a[MAXN];
    
    int main()
    {
    	scanf("%d%d", &n, &k);
    	REP(i, 0, k) a[i].read();
    	sort(a, a + k);
    	
    	memset(f, -63, sizeof(f));
    	f[0] = 0;
    	int p = 0;
    	_for(i, 1, n)
    	{
    		if(a[p].l == i)
    		{
    			while(a[p].l == i) 
    				f[a[p].r] = max(f[a[p].r], f[i-1]), p++;
    		}
    		else f[i] = max(f[i], f[i-1] + 1);
    	}
    	printf("%d
    ", f[n]);
    
    	return 0;
    }
  • 相关阅读:
    CF1037H
    CF1296F
    CF1446F
    CF1175G
    CF1146G
    CF1303G
    CF1067D
    CF1477E
    COJ16G
    ZJOI2018 迷宫
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819413.html
Copyright © 2020-2023  润新知