HDU 3646 DP + 二分

來源:互聯網
上載者:User

連結:http://acm.hdu.edu.cn/showproblem.php?pid=3646

題意:你有N把武器,每把武器可以對敵人造成一定的傷害(et:攻擊力500,敵人血量為200,殺死敵人,攻擊力剩餘300),一共有K個敵人,你有M次魔法double武器的攻擊力(加倍),使用武器是有規則的:武器有兩個狀態,一個狀態為young,一個為old,新的武器狀態為young,當你用它殺死一個敵人之後,狀態變為old,當狀態為young的時候,即使該武器剩餘的攻擊力不足以殺死當前的敵人,但是可以傷害他一定血量,但是為old的時候,武器攻擊力不足以殺死對方,就無法攻擊他(比如攻擊力為200,敵人血量500,young:敵人減少200,old:敵人血量不減)。使用武器的順序和殺人的順序是給定的。問你最多能殺死幾個人?

見解:如果沒有old,young的話,這是一個水DP,有了這個狀態的話,我們不好處理,主要是不知道當前武器的狀態是什麼,如果加一維表示目前狀態的話,那麼還得再來一維表示正在挑戰第幾個敵人,我們可以這樣理解狀態,dp【i】【j】表示使用完了i把武器,用了j次魔法,一共造成的傷害是多少,轉移的時候,二分下現在的傷害就能知道現在在殺第a個人,然後二分再使用一把武器的造成的傷害,能知道挑戰到第b個人,如果兩個人不是同一個人,那說明我們無法傷害b,那麼使用這把武器後我們能造成的傷害就是sum【b】了,最後二分傷害,就可以知道最多殺死幾個人了,詳細看代碼:

#include<stdio.h>#include<string.h>#include<algorithm>#define Max(a,b) ((a)>(b)?(a):(b))using namespace std;const int maxn = 105;const int maxm = 100005;int dp[2][maxn],life[maxm],power[maxn * maxn],N,M,K;int sum[maxm];int main(){    int cnt = 0;    while(scanf("%d%d%d",&N,&M,&K) && N + M + K)    {        for(int i = 1;i <= N;i ++) scanf("%d",&power[i]);        for(int i = 1;i <= K;i ++)        {            scanf("%d",&life[i]);            sum[i] = sum[i - 1] + life[i];        }        int ans = 0;        M = min(M,N);        memset(dp,0,sizeof(dp));        for(int i = 1;i <= N && !ans;i ++)        {            for(int j = 0;j <= M;j ++)            {                int a , b, next_a,next_b;                a = upper_bound(sum + 1,sum + 1 + K,dp[(i - 1) & 1][j]) - sum;// now killed                if(j)                {                    b = upper_bound(sum + 1,sum + 1 + K,dp[(i - 1) & 1][j - 1]) - sum;//now killed j - 1                    next_b = upper_bound(sum + 1,sum + 1 + K,dp[(i - 1) & 1][j - 1] + (power[i] << 1)) - sum;// use power                }                next_a = upper_bound(sum + 1,sum + 1 + K,dp[(i - 1) & 1][j] + power[i]) - sum;//not use power                int hurt_a = dp[(i - 1) & 1][j] + power[i],hurt_b ;                if(a != next_a) hurt_a = sum[next_a - 1];                if(j) hurt_b = dp[(i - 1) & 1][j - 1] + (power[i] << 1);                if(j) if(b != next_b) hurt_b = sum[next_b - 1];                if(j)dp[i & 1][j] = Max(hurt_a,hurt_b);                else dp[i & 1][j] = hurt_a;                if(dp[i & 1][j] >= sum[K])                {                    ans = K;                    break;                }            }        }        if(!ans) ans =  upper_bound(sum + 1,sum + 1 + K,dp[N & 1][M]) - sum - 1;        printf("%d\n",ans);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.