当前位置: 代码迷 >> 综合 >> 洛谷P1280 caioj 1085 动态规划入门(非常规DP9:尼克的任务)
  详细解决方案

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

热度:61   发布时间:2023-09-20 19:39:38.0

这道题我一直按照往常的思路想
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\n", 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\n", f[n]);return 0;
}

 

  相关解决方案