生活随笔
收集整理的這篇文章主要介紹了
HDU 3646 DP + 二分
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
鏈接: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 killedif(j){b = upper_bound(sum + 1,sum + 1 + K,dp[(i - 1) & 1][j - 1]) - sum;//now killed j - 1next_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 powerint 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;
}
轉載于:https://www.cnblogs.com/yobobobo/archive/2012/10/26/3826806.html
總結
以上是生活随笔為你收集整理的HDU 3646 DP + 二分的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。