码迷,mamicode.com
首页 > 其他好文 > 详细

A simple greedy problem(hdu 4976)

时间:2017-04-25 00:45:59      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:stream   一个人   pre   第一个   cst   sim   eof   names   情况   

题意:有n个小兵,每个小兵有a【i】血量,第一个人每次只能对一个小兵砍一滴血,第二个人每次对所有生存的小兵砍一滴血。

   最后看第一个人最多可以砍杀几个小兵。

/*
    首先,如果所有小兵的血量都不同的话,我们可以杀死所有的小兵,如果所以我们应该尽量使小兵血量不同,
    也就是在不能将某个小兵一击致命的情况下,对某个某个血量相同的小兵砍一刀,使其血量不同。
    预处理出c[i]表示i血量这个位置上的小兵是由c[i]血量的小兵砍过来的。
    dp[i][j]表示进行了i轮之后,留有的砍兵机会为j次的最大值。
    dp[i][j]=max(dp[i-1][j-1],dp[i-1][j+c[i]-i])
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1010
using namespace std;
int c[N],d[N],dp[N][N],s[N],n,m,top,cas;
int main(){
    int T;scanf("%d",&T);
    while(T--){
        m=0,top=0;
        memset(d,0,sizeof(d));
        memset(c,0,sizeof(c));
        memset(dp,0,sizeof(dp));
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int x;scanf("%d",&x);
            d[x]++;m=max(m,x);
        }
        for(int i=1;i<=m;i++){
            if(d[i]==1) c[i]=i;
            else if(d[i]==0) s[++top]=i;
            else {
                c[i]=i;
                while(top&&d[i]>1){
                    int x=s[top];
                    if(i-x<=top){
                        top--;
                        c[x]=i;
                        d[i]--;
                    }
                    else break;
                }
            }
        }
        for(int i=1;i<=m;i++)
            for(int j=0;j<=i;j++){
                if(j) dp[i][j]=dp[i-1][j-1];
                if(c[i]&&j+c[i]-i<i) dp[i][j]=max(dp[i][j],dp[i-1][j+c[i]-i]+1);
            }
        int ans=0;
        for(int i=0;i<=m;i++)
            ans=max(ans,dp[m][i]);
        printf("Case #%d: %d\n",++cas,ans);
    }
    return 0;
}

 

A simple greedy problem(hdu 4976)

标签:stream   一个人   pre   第一个   cst   sim   eof   names   情况   

原文地址:http://www.cnblogs.com/harden/p/6759441.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!