poj 1337 DP

dp【i】表示i时间之后所需做的最少工作时间,首先预处理下在某个时间点能做哪些工作

然后 dp[i] = min( dp[i], dp[i+v[i][j]] + v[i][j] );

如果不能做任何工作的话 dp【i】 = dp【i+1】

你可能会想,这样弄的话,某些工作会不会重复的做呢?

答案是不能能的!

因为    ti <= ai - bi <= 2 * ti 

所以某一工作在他允许的范围内做了之后就不可能做第二次

这提要注意时间是从0开始的。。。。。。

AC代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

#define MAX 0x3f3f3f3f

struct Node{
    int a, b, t;
};

Node node[110];
vector<int> v[300];
int N;
int dp[260];

int main(){
    int T;
    cin >> T;
    while( T-- ){
        cin >> N;
        for( int i = 0; i < N; i++ ){
            cin >> node[i].t >> node[i].a >> node[i].b;
        }
        for( int i = 0; i <= 250; i++ ){
            v[i].clear();
        }
        for( int i = 0; i <= 250; i++ ){
            for( int j = 0; j < N; j++ ){
                if( node[j].a <= i && node[j].t + i <= node[j].b ){
                    v[i].push_back( node[j].t );
                }
            }
        }
        memset( dp, 0x3f, sizeof( dp ) );
        dp[251] = 0;
        for( int i = 250; i >= 0; i-- ){
            if( v[i].size() == 0 ){
                dp[i] = dp[i+1];
            }else{
                int temp;
                for( int j = 0; j < v[i].size(); j++ ){
                    dp[i] = min( dp[i], dp[i+v[i][j]] + v[i][j] );
                    temp = dp[i];
                }
            }
        }
        cout << dp[0] << endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值