您的位置:首页 > 其它

zoj 3623

2012-09-25 10:49 204 查看
地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4769

题意:输入n,l,n代表有n种船可以造,l代表怪物的血量。再输入n行,每行两个数,分别代表造船的时间和船的攻击力,船造好之后可以一直攻击敌人,求打死敌人的最短时间。

mark:这居然是个完全背包的题。真的是没想到,看解题报告看了好久才看懂。

   把每条船时间当成体积,攻击力当成价值,dp[j]存放时间j最多能打敌人多少血。dp[j] = max(dp[j], dp[j-v[i]]+(j-v[i])*w[i]);

   分析:这个转换的时候可以这样理解,后面加的(j-v[i])*w[i]是说第一秒的时候造的i船,然后它可以攻击(j-v[i])秒,所以造成的伤害是(j-v[i])*w[i],则dp[j-v[i]]就代表除去第一秒造i船的伤害,别的在时间j内的伤害最大值。(仔细体会体会……)

   还有的解题报告说dp[i][j]可以代表怪物掉了i血,当前攻击力为j的时候最小的时间。则dp[i][j] = min(dp[i][j], dp[i-t[k]*(j-l[k])][j-l[k]]), (0 <= k < n);意思是最后一次造的k船,则在准备造这条船的时候的状态就是dp[i-t[k]*(j-l[k])][j-l[k]].代码就不给了。http://blog.csdn.net/wconvey/article/details/7804524

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int N = 35;
const int M = 1000;
int n,l;
int v
,w
;
int dp[M];

int max(int a, int b) {return a > b ? a : b;}

int main()
{
int i,j,k;
while(~scanf("%d%d", &n, &l))
{
for(i = 0; i < n; i++)
scanf("%d%d", v+i, w+i);
memset(dp, 0, sizeof(dp));
for(i = 0; i < n; i++)
for(j = v[i]; j <= v[i]+l; j++)
dp[j] = max(dp[j], dp[j-v[i]]+(j-v[i])*w[i]);
for(i = 0; i < v[i]+330; i++)
if(dp[i] >= l)
{
printf("%d\n", i);
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: