您的位置:首页 > 其它

hdu4976 A simple greedy problem. (贪心+DP)

2014-08-21 19:33 330 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4976

2014 Multi-University Training Contest 10

1006

A simple greedy problem.

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 20 Accepted Submission(s): 4


[align=left]Problem Description[/align]

//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define usll unsigned ll
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(i=0;i<(n);i++)
#define FOR(i,x,n) for(i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) prllf("%d\n",x);
#define RE  freopen("D.in","r",stdin)
#define WE  freopen("1biao.out","w",stdout)
#define mp make_pair
#define pb push_back
int n;
int d[1111];///d[i] i血怪有多少个
int c[1111];///c[i] 在i位置应该补的怪本来在c[i]位置(本来是个c[i]血怪
int f[1111][1111];///f[i][j],AOE杀i血怪前,我攻击结束后,我预留攻击还剩下j次,最多杀多少怪(包括i血怪)
int main() {
int t,n,i,j;
int x;
int cas=1;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
mz(d);
int ma=0;
REP(i,n) {
scanf("%d",&x);
d[x]++;
ma=max(x,ma);
}
int b[1111],bn=0;
mz(c);
int need;
for(i=1; i<=ma; i++) {
if(d[i]!=0) {
while(d[i]>1) {
if(bn>0) need=i-b[bn-1];///需要need步把它射到最后一个零处,然后还用b[r-1]这1步把它射死
else break;///没有剩余的零就跳出
//printf("i=%d,need=%d,r=%d,l=%d,r-l=%d,b[%d]=%d,b[%d]=%d\n",i,need,r,l,r-l,l+need-1,b[l+need-1],r-1,b[r-1]);
if(need+1<=bn) { ///空闲的步数足以把它射到最后一个空格(b[bn-1])处
c[b[bn-1]]=i;
bn--;///把这个零用掉
d[i]--;
} else break;///空闲步数不够就跳出
}
c[i]=i;///补这个怪
} else {
b[bn++]=i;///记录零
}
}
//        for(i=1;i<=ma;i++)
//            printf("%3d",c[i]);
//        puts("");
mz(f);
for(i=1; i<=ma; i++) {
for(j=0; j<=i; j++) {
if(j>0)f[i][j]=f[i-1][j-1];///这次不打,存一个攻击机会
if(c[i]!=0 && j+c[i]-i < i ) f[i][j]=max(f[i][j] , f[i-1][j+c[i]-i]+1);///怒把这个小兵打爆
}
}
int ans=0;
for(j=0; j<ma; j++)
ans=max(ans,f[ma][j]);
printf("Case #%d: %d\n",cas++,ans);
}
return 0;
}


View Code

(比赛时第二个看这个题,因为他题目上写着贪心嘛,看起来很水的样子!我也有点思路,写了个贪心,每次把怪垫到之前最后的零的位置,完全没想到这样不是最优……居然还要DP才行,怕了,被题目骗了!)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: