zoj 3623 Battle Ships

思路: 完全背包
分析:
1 有n种战舰和敌人的总的血量L,每一种战舰的创建时间为ti,每秒钟对敌人的伤害的血量为li
2 当敌人的血量为0的时候玩家赢了,求玩家最少的时间赢了游戏
3 这边如果我们用血量去做背包dp[j]表示伤害血量为j的最小时间的话,状态转移方程无法推出,那么我们考虑用时间去做背包dp[j]表示时间为j的最大伤害血量,那么我们从小到达枚举时间k,只要找到一个dp[k] >= L,说明玩家赢了
4 很容易写出状态转移方程k表示时间为k,dp[k] = max(dp[k] , dp[k-[ti]+(k-t[i])*l[i]);很好理解如果不创建第i个战舰就是dp[k],再创建第i个就是dp[k-t[i]]+(k-t[i])*l[i])为什么是这样的呢?因为总的时间为k那么攻击的时间为k-t[i],所以伤害的血量为(k-t[i])*l[i]

代码:


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

const int MAXN = 610;

int n , sum;
int t[MAXN] , l[MAXN];
int dp[MAXN];

int solve(){
    for(int k = 1 ; k <= 600 ; k++){
        memset(dp , 0 , sizeof(dp));
        for(int i = 1 ; i <= n ; i++){
            for(int j = t[i] ; j <= k ; j++)
                dp[j] = max(dp[j] , dp[j-t[i]]+(j-t[i])*l[i]);
            if(dp[k] >= sum)
                return k;
        }
    }
}

int main(){
    while(scanf("%d%d" , &n , &sum) != EOF){
        for(int i = 1 ; i <= n ; i++)
            scanf("%d%d" , &t[i] , &l[i]);
        printf("%d\n" , solve());
    } 
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值