Hurdles of 110m 【DP 背包】

一共有N段过程,每段过程里可以选择 快速跑、 匀速跑 和 慢速跑

对于快速跑会消耗F1 的能量, 慢速跑会集聚F2的能量

选手一开始有M的能量,即能量上限

求通过全程的最短时间

定义DP[i][j] 为跨越第 i 个栏,剩余 j 点能量

动态转移方程

dp[i][j] = min(dp[i][j], dp[i-1][j-F1]+T1)    (Fast Mode)

dp[i][j] = min(dp[i][j], dp[i-1][j]+T2)     (Normal Mode)

dp[i][j] = min(dp[i][j], dp[i-1][j+F2]+T3)   (Slow Mode)

Source Code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-7      ;
const int N = 22             ;
const int M = 1100011*2      ;
const ll P = 10000000097ll   ;
const int MAXN = 100000      ;
const int INF = 0x3f3f3f3f   ;
const int MAX = 10500        ;

struct sc{
    int t1, t2, t3, f1, f2;
}a[120];

int n, m;
int dp[120][120];

int main(){
    std::ios::sync_with_stdio(false);
    int i, j, t, k, l, u, v, x, y, numCase = 0;
    cin >> t;
    while(t--){
        cin >> n >> m;
        for(i = 0; i < n; ++i){
            cin >> a[i].t1 >> a[i].t2 >> a[i].t3 >> a[i].f1 >> a[i].f2;
        }
        memset(dp, 0x3f, sizeof(dp));
        dp[0][m] = 0;
        for(i = 0; i < n; ++i){
            for(j = 0; j <= m; ++j){
                if(j >= a[i].f1){
                    checkmin(dp[i + 1][j - a[i].f1], dp[i][j] + a[i].t1);
                }
                if(j + a[i].f2 > m){
                    checkmin(dp[i + 1][m], dp[i][j] + a[i].t3);
                } else{
                    checkmin(dp[i + 1][j + a[i].f2], dp[i][j] + a[i].t3);
                }
                checkmin(dp[i + 1][j], dp[i][j] + a[i].t2);
            }
        }
        int ans = INF;
        for(i = 0; i <= m; ++i){
            checkmin(ans, dp[n][i]);
        }
        cout << ans << endl;
    }

    return 0;
}
时间: 2024-11-05 02:55:42

Hurdles of 110m 【DP 背包】的相关文章

【TOJ 1545】Hurdles of 110m(背包题)

描述 In the year 2008, the 29th Olympic Games will be held in Beijing. This will signify the prosperity of China and Beijing Olympics is to be a festival for people all over the world as well. Liu Xiang is one of the famous Olympic athletes in China. I

HDU 1011 Starship Troopers(树形dp+背包)

Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13109    Accepted Submission(s): 3562 Problem Description You, the leader of Starship Troopers, are sent to destroy a base of

POJ 3132 Sum of Different Primes DP背包

http://poj.org/problem?id=3132 题意: 给定n和k,问用恰好k个不同的质数来表示n的方案数. 分析: n和k都很小.反正就是个背包,选k个物品恰好填满n即可. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 bool dp[1200][15]; 6 int ct[1200][15]; 7 int p[1200]; 8 bool a[1200]; 9 int n, k,

二叉苹果树(树型DP+背包)

二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树: 2   5 \  / 3  4 \  / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 程序名:apple 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=

hdu1011 树形dp背包

http://acm.hdu.edu.cn/showproblem.php?pid=1011 Problem Description You, the leader of Starship Troopers, are sent to destroy a base of the bugs. The base is built underground. It is actually a huge cavern, which consists of many rooms connected with

Poj 1112 Rebuilding Roads(树形DP+背包)

题意:给你由N个点构成一颗树,问要孤立出一个有P个节点的子树最少需要删除多少条边.N的范围最大为150 N的范围不大,很容易想到在树上面做背包.把每个节点都看成一个背包,然后把每个儿子节点都看成是一组物品.为什么是一组呢,那是因为假设以儿子为根的节点的子树有S个节点,那么就有S+1种情况,要么将这整棵子树舍弃,要么从这个子树中取1-S个节点. 设f[i][j]为以i为根节点的子树,孤立出以i为根节点,一共含有j个节点的子树最少需要删除的边数(不包括删除i和他父亲的连接的那条边(假设i不是根节点)

HDU 1561 The more, The Better(树形dp+背包)

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6000    Accepted Submission(s): 3548 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻

POJ3345---Bribing FIPA(树形dp+背包)

Description There is going to be a voting at FIPA (Fédération Internationale de Programmation Association) to determine the host of the next IPWC (International Programming World Cup). Benjamin Bennett, the delegation of Diamondland to FIPA, is tryin

URAL_1018 Binary Apple Tree 树形DP+背包

这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过程中,有点难表示转移 后来看了下大神的做法才知道其实可以用背包来模拟 树枝的去留,其实真的是个背包诶,每个子树枝就相当于物品,他占用了多少树枝量,带来多少的收益,就是用背包嘛,于是用树形DP+背包就可以做了 #include <iostream> #include <cstdio> #

HDU 4901 DP背包

给你n个数,问你将数分成两个数组,S,T ,T 中所有元素的需要都比S任意一个大,问你S中所有元素进行 XOR 操作和 T 中所有元素进行 &操作值相等的情况有多少种. DP背包思路 dpa[i][j][0]  表示从左开始到i,不取i,状态为j的方案数 dpa[i][j][1]  表示从作开始到i,取i,状态为j的方案数 dpb[i][j]      表示从右开始到i,状态为j的方案数 因为S集合一定在T集合的左边,那么可以枚举集合的分割线,并且枚举出的方案要保证没有重复,如果要保证不重复,只