hdu 5234 Happy birthday【动态规划】

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5234

题意:给出一个n*m的矩阵和一个整数k,要求从左上角开始只能往右

或者往左开始遍历,在途中可以选择加当前位置的数或者不加当前位

置的数,求最终加的数的和小于k的最大值。

分析:这道题一看就是一般的背包,但是没研究过背包和dp,只是凭

这感觉写了状态转移方程,wa了几次A了,感觉dp是个很好的东西,只

是自己图论还没学好就从来没弄过这个,其实还是可以学学的。

首先先说一下背包九讲里面的第一个内容吧,原文是这样的:

有N件物品和一个容量为V的背包。第i件物品的体积是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

状态转移方程:

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的

伪码:

for i=1..N

for v=V..0

f[v]=max{f[v],f[v-c[i]]+w[i]};

如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,

价值为f[i-1][v];

如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,

此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。

②例题二:

采药

Time Limit:   1000MS       Memory Limit:   65535KB

Submissions:   155       Accepted:   50

Description辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

Input输入的第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

Output输出包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

Sample Input

70 3

71 100

69 1

1 2

Sample Output

3

#include<iostream>

# include<cstring>

# define max(a,b) a>b?a:b

using namespace std;

int main()

{

int dp[101][1001],m,T,w[101],val[101],i,j;

cin>>T>>m;

for(i=1;i<=m;i++)

cin>>w[i]>>val[i];

memset(dp,0,sizeof(dp));

for(i=1;i<=m;i++)

for(j=0;j<=T;j++)//j相当于上面说的V-c[i]

{

if(j>=w[i])

dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+val[i]);//放还是不放的选择

else dp[i][j]=dp[i-1][j];

}

cout<<dp[m][T]<<endl;

return 0;

}

而这道题和上面应该是一样的,只不过是二维的,那木状态转移方程可以是:

dp [i][j][l]=max{ dp[i-1][j][l-map[i][j]]+map[i][j],dp[i][j-1][l-map[i][j]]+map[i][j],dp[i-1][j][l],dp[j][i-1][l]}

献上代码:

#include<stdio.h>

#include<string.h>

#include<algorithm>

#include<iostream>

using namespace std;

const int maxn=100+10;

int map[maxn][maxn],dp[maxn][maxn][maxn];

int Max(int x,int y)

{

return x>y?x:y;

}

int main()

{

int n,m,k;

int l1,l2,l3,l4;

while(~scanf("%d%d%d",&n,&m,&k))

{

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

scanf("%d",&map[i][j]);

memset(dp,0,sizeof(dp));

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

for(int l=0;l<=k;l++)

{

l1=l2=l3=l4=0;

l1=dp[i-1][j][l];

l2=dp[i][j-1][l];

if(l>=map[i][j])

{

l3=dp[i-1][j][l-map[i][j]]+map[i][j];

l4=dp[i][j-1][l-map[i][j]]+map[i][j];

dp[i][j][l]=Max(Max(l1,l2),Max(l3,l4));

}

else

dp[i][j][l]=Max(l1,l2);

}

printf("%d\n",dp[n][m][k]);

}

return 0;

}

时间: 2025-01-02 03:46:00

hdu 5234 Happy birthday【动态规划】的相关文章

HDU 5234 Happy birthday 动态规划(三维数组)

题目大意:过生日,有一个N*M的表格,每个位置都有一块一定重量的蛋糕你可以选择吃完或者不吃,从(1,1)走到(n,m),每次只能向右走或向下走,最多能吃k重量的蛋糕.问你最多能吃多少蛋糕. 题目思路:之前的01背包我们都是用一维数组v[]来储存的,但这次要用二维数组Map[i][j]储存一个点的价值,当前点由Map[i][j-1]或Map[i-1][j]走到. 状态转移方程式:dp[i][j][q]=max(dp[i][j][q],Map[i][j]+max(dp[i][j-1][q-Map[i

[ACM] hdu 1260 Tickets (动态规划)

Tickets Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 4   Accepted Submission(s) : 2 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Jesus, what a great movie! Thou

hdu 1494 跑跑卡丁车(动态规划)

Problem Description 跑跑卡丁车是时下一款流行的网络休闲游戏,你可以在这虚拟的世界里体验驾驶的乐趣.这款游戏的特别之处是你可以通过漂移来获得一种加速卡,用这种加速卡可以在有限的时间里提高你的速度.为了使问题简单化,我们假设一个赛道分为L段,并且给你通过每段赛道的普通耗时Ai和用加速卡的耗时Bi.加速卡的获得机制是:普通行驶的情况下,每通过1段赛道,可以获得20%的能量(N2O).能量集满后获得一个加速卡(同时能量清0).加速卡最多可以储存2个,也就是说当你有2个加速卡而能量再次

HDU 5234 Happy birthday --- 三维01背包

HDU 5234 题目大意:给定n,m,k,以及n*m(n行m列)个数,k为背包容量,从(1,1)开始只能往下走或往右走,求到达(m,n)时能获得的最大价值 解题思路:dp[i][j][k]表示在位置(i,j)有一个容量为k的背包所能获得的最大价值 决策:a[i][j]处的数是否选取 不选取: dp[i][j][k]= max(dp[i-1][j][k], dp[i][j-1][k]) 选取:首先要求k >=a[i][j],那么dp[i][j][k] = max(dp[i-1][j][k-w[i

HDU 2829 Lawrence(动态规划-四边形不等式)

Lawrence Problem Description T. E. Lawrence was a controversial figure during World War I. He was a British officer who served in the Arabian theater and led a group of Arab nationals in guerilla strikes against the Ottoman Empire. His primary target

hdu 5234 Happy birthday 背包 dp

Happy birthday Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5234 Description 今天是Gorwin的生日.所以她的妈妈要实现她的一个愿望.Gorwin说她想吃很多蛋糕.所以他妈妈带她来到了蛋糕园. 这个园子被分成了n*m个方格子.在每一个格子里面,有一个蛋糕.第i行,第j列的格子中有一个重量为wij千克的蛋糕,Gorwin从左上角(1,1

HDU 5234 Happy birthday 01背包

题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5234 bc:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=585&pid=1003 题解: 由于数据比较小,所以可以转化为判定性问题,即: dp[i][j][kk]表示走到i,j这一点时吃了kk重的蛋糕,转移方程只要考虑这一点的蛋糕吃和不吃两种情况(01背包) 代码: 1 #include<ios

hdu 4405 Aeroplane chess 动态规划

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4405 所谓概率DP大多是算期望 算期望大多是从终点往回推 简单的1维动态规划 dp[i]表示第i格到终点的期望步数 从终点往前推 若当前为某条捷径的起点 那么该点的dp值直接等于捷径终点的dp值 否则枚举掷出1到6时所到的位置的期望 用最朴素的方法求期望 dp[0]即为所求 #include <cstdio> #include <cstdlib> #include <ctime&

[HDU 5074] Hatsune Miku (动态规划)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5074 题目大意是给你m个note,n个数,得分是v[a[i]][a[i+1]]的总和,如果说a[i]是负数的话代表可以放人一个note,否则就只能放他给的note号. 问:最大的得分是多少? 我先写了记忆化搜索函数 dp(i,j)代表到第i个位置,放标号为j的note 那么 如果说a[i+1]<0,那么dp(i,j) = max( dp(i,j) , dp(i+1,k)+v[j][k] ); 否则d