题目链接: http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=774&pid=1003

  题目大意: a[i], b[i] | 0 <= i <= n .................... k[j],  p[j] | 0 <= j <= m,  n个魔王, m中法术方式, 每个法术攻击p[j], 消耗k[j]水晶,   每个魔王a[i]生命, b[i]护甲, 攻击必须先打穿护甲, 求杀死所有魔王的最少水晶数。

  解题思路: dp[i][j] 表示一个魔王血量为i 护甲为 j 的时候, 杀死它需要的最少水晶, 哦对了, 水晶无限,  所以就转换成n个完全背包问题, 再加和。

  代码: 下面我的代码有错, 不知道哪儿错了

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <iterator>
#include <cmath>
#include <algorithm>
#include <stack>
#include <deque>
#include <map>

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1

const int maxn = 1e5+100;
const int maxm = 1e3 + 100;
const int maxa = 1e3 + 100;
const int maxb = 15;
using namespace std;
const int INF = 0x3fffffff;

int a[maxn];
int b[maxn];
int k[maxm];
int p[maxm];
int dp[maxa][maxb]; // dp(i, j)生命值为i , 防御值为 j 的时候消灭它花费最少


int main() {
    int n, m;
    while( scanf( "%d%d", &n, &m ) == 2 ) {
        
        int defend = 0;
        int attack = 0;
        int ma = 0;
        for( int i = 1; i <= n; i++ ) {
            scanf( "%d%d", a+i, b+i );
            defend = max( defend, *(b+i) );
            ma = max( ma, *(a+i) );
        }
        for( int i = 1; i <= m; i++ ) {
            scanf( "%d%d", k+i, p+i );
            attack = max( attack, *(p+i) );
        }
        if( attack <= defend ) {
            printf( "-1\n" );
            continue;
        }
        for( int i = 0; i <= ma; i++ ) {
            for( int j = 0; j <= defend; j++ ) {
                if( i == 0 ) dp[0][j] = 0;
                else dp[i][j] = INF;
            }
        }
        for( int i = 1; i <= ma; i++ ) {
            for( int j = 0; j <= defend; j++ ) {
                for( int t = 1; t <= m; t++ ) {
                    if( j > p[t] ) continue;
                    else if( i - (p[t]-j) >= 0 ) {
                        dp[i][j] = min( dp[i][j], dp[i-(p[t]-j)][j]+k[t] );
                    }
                    else dp[i][j] = min( dp[i][j], dp[0][j]+k[t] );
                }
            }
        }
        long long res = 0;
        for( int i = 1; i <= n; i++ ) {
            res += dp[a[i]][b[i]];
        }
        printf( "%lld\n", res );
    }
    return 0;
}
View Code

相关文章: