hdu 4976 A simple greedy problem.

题意:

有n个小兵,每一个小兵有a【i】血量,第一个人每次仅仅能对一个小兵砍一滴血,第二个人每次对全部生存的小兵砍一滴血。最后看第一个人最多能够砍杀几个小兵。

思路:

这个就是游戏中所说的垫刀问题。首先是不一样的越多那么第一个人所补得刀数就越多。

那么就要考虑要多少刀把当前的小兵的血量砍得和别人不一样。

用W【i】表示砍了i刀之后与其它的血量不一样的原始血量

用dp[i][j],表示进行了i组攻击(第一个攻击一次,第二个攻击一次,称为一组)。第一个留有j次攻击,最多能杀死的小兵数目。

那么在第i组攻击的时候j的范围是【0。i+1】 ,由于第一个人能够有i+1次的机会

那么dp转移方程就是 dp【i+1】【t】 = max(dp【i】【j】+1。dp【i+1】【t】)(t = i+ j +1 -w[i+1] )

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define N 1111
int n;
int a[N];
int dp[N][N];
int w[N];

int main(){
    int T;
    int cas = 0 ;
    scanf("%d",&T);
    while(T--){
    	scanf("%d",&n);
    	memset(w,-1,sizeof(w));
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}

    	sort(a+1,a+n+1);
//求a【i】边的不一样须要补多少刀
        for(int i=1;i<=n;i++){
        	for(int j=a[i];j>0;j--){
               if(w[j]==-1){
               	 w[j] = a[i];
               	 break;
               }
        	}
        }
        for(int i=1;i<=a[n];i++){
            printf("%d %d\n",w[i],i);
        }

        memset(dp,-1,sizeof(dp));

        dp[0][0]=0;
        for(int i=0;i<a[n];i++){
        	for(int j = 0;j<=i+1;j++){
        		if(dp[i][j]!=-1){
                   dp[i+1][j+1] = max(dp[i+1][j+1],dp[i][j]);
                   int ok = j+i+1 - w[i+1];
                   if(w[i+1]!=-1&&ok>=0){
                   	dp[i+1][ok] = max(dp[i+1][ok],dp[i][j]+1);
                   }
        		}

        	}
        }
        /*
        for(int i = 0;i<=a[n];i++)
        {
        for(int j = 0; j <= a[n] ; j ++){
            printf("%2d ",dp[i][j]);
        }
        puts("");
        }
        */
        int ans = 0;
        for(int j = 0; j <= a[n] ; j ++)
            ans = max(ans, dp[a[n]][j]);
        printf("Case #%d: %d\n",++cas,ans);
    }

}
时间: 2024-11-05 19:30:30

hdu 4976 A simple greedy problem.的相关文章

HDU 4976 A simple greedy problem. 贪心+DP

题意: 给定n<=1000个小兵,A每次都能使小兵掉1点血,B每次能使所有小兵掉1点血,A.B轮流攻击,每次轮到A他会选择是否攻击,轮到B必须攻击.求A最多能杀死多少小兵.(当小兵血量为1时被攻击到视为被杀死) 思路: 如果所有小兵血量都不一样,A必定能杀死所有小兵.如果有小兵血量相同,那么A必定会攻击一些小兵使他们血量不同.所以我们可以把A的攻击分为两类:用来刚好杀死小兵的一次, 和用来使小兵血量不同的攻击. 我们可以用贪心的思想预处理出怎样用最小的攻击次数让小兵的血量都不同. 然后我们可以用

hdu 4974 A simple water problem(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4974 Problem Description Dragon is watching competitions on TV. Every competition is held between two competitors, and surely Dragon's favorite. After each competition he will give a score of either 0 or

HDU 4974 A simple water problem(贪心)

HDU 4974 A simple water problem 题目链接 签到题,很容易贪心得到答案是(sum + 1) / 2和ai最大值的最大值 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100005; typedef long long ll; int t, n; ll a, Max, sum; int main(

HDU - 4974 A simple water problem

Problem Description Dragon is watching competitions on TV. Every competition is held between two competitors, and surely Dragon's favorite. After each competition he will give a score of either 0 or 1 for each competitor and add it to the total score

2014多校第十场1004 || HDU 4974 A simple water problem

题目链接 题意 : n支队伍,每场两个队伍表演,有可能两个队伍都得一分,也可能其中一个队伍一分,也可能都是0分,每个队伍将参加的场次得到的分数加起来,给你每个队伍最终得分,让你计算至少表演了几场. 思路 : ans = max(maxx,(sum+1)/2) :其实想想就可以,如果所有得分中最大值没有和的一半大,那就是队伍中一半一半对打,否则的话最大的那个就都包了. 1 #include <cstdio> 2 #include <cstring> 3 #include <st

hdu 1757 A Simple Math Problem (乘法矩阵)

A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2441    Accepted Submission(s): 1415 Problem Description Lele now is thinking about a simple function f(x).If x < 10 f(x) =

hdu4976 A simple greedy problem.

A simple greedy problem. Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 476    Accepted Submission(s): 193 Problem Description Victor and Dragon are playing DotA. Bored of normal games, Victor

HDU 4974 A simple water problem 模拟(水

水题. #include <cstdio> #include <iostream> #include <queue> #include <algorithm> using namespace std; typedef long long ll; priority_queue<int> q; int main() { int T, cas = 0; scanf("%d", &T); while(T-- > 0) {

HDU 4978 A simple probability problem

A simple probability problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 43    Accepted Submission(s): 14 Problem Description Equally-spaced parallel lines lie on an infinite plane. The sep