ZOJ - 3623 Battle Ships(完全背包或者BFS)

来源:互联网 发布:最优化文章 编辑:程序博客网 时间:2024/06/05 21:17

题目大意:有一只boss,血量为L
你有N招技能,每招技能都有相应的蓄能时间,释放后,能每秒造成K点伤害
问至少需要几秒才能干掉boss

解题思路:我能说这题我是用bfs解决的吗 。。。
用dp[i][j]表示在第j秒,造成的伤害为i时,每秒能造成的伤害

参考了一下别人的,神奇的思路:
用dp[i + time[j]]表示在 i + time[j] 这个时刻所能造成的总伤害的最大值
转移方程为dp[i + time[j]] = max(dp[i + time[j]], dp[i] + l[j] * i)
time表示造船时间,l表示造成的持续伤害
这个转移方程表示的是,用i + time[j]这段时间的0-time[j]这段时间造了第j艘船,然后这艘船在总时间内造成的伤害就有i * l[j]了
因为还有i这段时间,i这段时间所造成的伤害就是dp[i]了
所以就有上述的转移方程了

BFS解法:卡时间过的 所以提交的时候不一定会A了,有可能TLE

#include <cstdio>#include <cstring>#include <queue>using namespace std;const int N = 350;const int INF = 0x3f3f3f3f;struct Ship{    int t, l;}S[35];struct Node {    int des, time;    Node() {}    Node(int des, int t): des(des), time(t) {}};int n, l;int dp[N][N];void init() {    for (int i = 0; i < n; i++)        scanf("%d%d", &S[i].t, &S[i].l);}void solve() {    memset(dp, 0, sizeof(dp));    queue<Node> Q;    Q.push(Node(0, 0));    int ans = INF;    while (!Q.empty()) {        Node t = Q.front(); Q.pop();        if (dp[t.des][t.time]) {            int used = (l - t.des) / dp[t.des][t.time];            if ((l - t.des) % dp[t.des][t.time]) used++;            ans = min(t.time + used, ans);        }        for (int i = 0; i < n; i++) {            int des = t.des + ( dp[t.des][t.time] * S[i].t);            int time = t.time + S[i].t;            if (des >= l) {                ans = min(ans, time);                continue;            }            if (des >= N || time >= N) continue;            if (dp[t.des][t.time] + S[i].l > dp[des][time]) {                dp[des][time] = dp[t.des][t.time] + S[i].l;                Q.push(Node(des, time));            }        }    }    printf("%d\n", ans );}int main() {    while (scanf("%d%d", &n, &l) != EOF) {        init();        solve();    }    return 0;}

背包解法:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 333;int t[N], l[N], dp[N];int n, m;void init() {    for (int i = 0; i < n; i++)        scanf("%d%d", &t[i], &l[i]);}void solve() {    memset(dp, 0, sizeof(dp));    for (int i = 0; i < 333; i++)        for (int j = 0; j < n; j++)            if (i + t[j] < 333)                dp[i + t[j]] = max(dp[i + t[j]], dp[i] + l[j] * i);    for (int i = 0; i < 333; i++)        if(dp[i] >= m) {            printf("%d\n", i);            return ;        }}int main() {    while (scanf("%d%d", &n, &m) != EOF ) {        init();        solve();    }    return 0;}
0 0
原创粉丝点击