HDU-4310 Hero 贪心Or动态规划

这题用贪心是很容易过的,直接先杀死对方单位时间输出较高的对象。

这题的动态规划解是将N个敌人压缩到一个int数里面,dp[j] 表示在剩余了j这个数里面所蕴含的敌人的情况下的最大扣血量。

dp方程为 dp[s] = min( dp[s - {bit}] + sumdps[s] * h[bit] ) 其中bit枚举每一位。

代码如下:

#include <cstdlib>

#include <cstring>

#include <cstdio>

#include <algorithm>

using namespace std;



int dp[1200000], N, h[30], dps[30], c[1200000], sum[1200000];



// dp[j] 代表剩余j数字所含二进制位的敌人所扣的最少血量



void dfs(int x, int num, int step, int tot)

{

    if (step == N) {

        c[x] = num;

        sum[x] = tot;

        return;

    }

    dfs(x<<1, num, step+1, tot);

    dfs(x<<1|1, num+1, step+1, tot+dps[N-step]);

}



void DP()

{

    int lim = 1 << N;

    for (int i = N-1; i >= 0; --i) {

        for (int j = 0; j < lim-1; ++j) {

            if (c[j] == i) {

                for (int k = 0; k < N; ++k) {    

                    if (!(j & (1<<k))) {

                        dp[j] = min(dp[j], dp[j|(1<<k)] + sum[j|(1<<k)] * h[k+1]);

                    }

                } 

            }

        }

    }

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

}



int main()

{

    while (scanf("%d", &N) == 1) {

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

        for (int i = 1; i <= N; ++i) {

            scanf("%d %d", &dps[i], &h[i]);

        }

        dfs(0, 0, 0, 0);

        dp[(1<<N)-1] = 0;

        DP();

    }

    return 0;

}

你可能感兴趣的:(动态规划)