[Nick] linear dynamic programming tasks

The amount of an emergent problem, stunned to do a few hours

 

General idea of ​​dynamic programming is still looking for a transfer

Another is the impact of the word

 

We can clearly see that the rules of this question:

When spare time, a task must be met to pick a pick

Seeking 1-n Maximum time spare time

 

So the task of sorting is necessary, two keywords

 

Imagine that when I do come back on a time task, I ST [i] - ( ST [i] t + [i] -1 when) inevitable at work

Then 1- (st [i] + t [i] -1) in the sections,

I was on a mission f [j] and the j time between tasks spare decision

The question now is to find out so legitimate j task, then add st [i] -st [j] -t [j]

Legitimate j task should it meet any requirements

st [i] before has been completed, but it has not done for too long

This condition can not be completed for too long, in fact, being the most likely to push,

That is, j + 1 task next number, that is the first to begin,

So we need a new array, the first pre-start

 

Of course, I really do not want this array

So I think every point of the current task, the task to update a later point

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring> 
using namespace std;
int m,n;
const int N=10003;
struct node
{
    int st,ed;//这里是左闭合,右开 
    bool operator < (const node & o) const
    {
        if(st!=o.st) return st<o.st;
        else return ed<o.ed;
    }
}d[N];
int f[N];

int main()
{
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&d[i].st ,&d[i].ed ),d[i].ed +=d[i].st ;
    d[++n].st =m+1,d[n].ed =m+1;
    sort(d+1,d+n);
    
    memset(f,-1,sizeof(f));
    int i=2;
    f[1]=d[1].st -1;
    while(i<n && d[i].st ==d[1].st ) f[i++]=f[1];
    
    for(i=1;i<n;i++)
    {
        if(f[i]==-1) continue;
        int nx=i+1;
        while(nx<n && d[nx].st <d[i].ed ) nx++;
        
        //printf("%d %d\n",d[i].st ,d[i].ed );
        int dis=d[nx].st -d[i].ed ;
        for(int j=nx;j<=n && d[j].st ==d[nx].st ;j++)
        {
            f[j]=max(f[i]+dis,f[j]);
            //,printf(" %d %d %d\n",d[j].st ,d[j].ed ,f[j]);
            //if(d[j].st ==9994) printf("%d %d %d\n",i,f[i],dis);
        }
    }
    
    printf("%d\n",f[n]);
    return 0;
} 

 

//倒序做
//为什么? 
#include<cstdio>
#include<cstdlib>
#include<algorithm> 
#include<vector>
using namespace std;
int m,n;
const int N=10003;
vector <int> t[N];
int f[N];

int main()
{
    scanf("%d%d",&m,&n);
    int st,ed;
    for(int i=1;i<=n;i++)
        scanf("%d%d",&st ,&ed ),ed +=st ,t[st ].push_back(ed);
    
    for(int i=m;i;i--)
    {
        int sz=t[i].size();
        if(!sz) 
        {
            f[i]=f[i+1]+1;
            continue;
        }
        for(int j=0;j<sz;j++)
        {
            ed=t[i][j];
            f[i]=max(f[i],f[ed ]);
        }
    }
    
    printf("%d\n",f[1]);
    return 0;
} 

 

Guess you like

Origin www.cnblogs.com/xwww666666/p/11357205.html