您的位置:首页 > 其它

NBUT 1153 Hero May Die But the King Will Never

2015-04-15 12:00 169 查看
题意就是勇士给国王当肉盾,每个勇士最多挡s秒就回家洗洗睡了,然后下一个勇士至少在他离开后b秒才会到来,攻击总共持续m秒,求国王所受最小伤害

首先考虑到抵挡时间可以小于s秒,其次两个勇士之间间隔可能会大于b秒,但是不会大于b+m秒,否则则这段空闲时间内就可以再多出一个勇士来防御了,不是最优解。

然后就定下来思路了,用数组储存前x秒攻击之和为sum[x]。

状态dp[x]定义为从x秒开始到结束所受最小伤害,转移方程为dp[x]=min{sum[i+b]-sum[i]+dp[i+b+1] | x<=i<x+sut}

以及 dp[x]=min{sum[i]-sum[x-1]+sum[i+b+sti]-sum[i+s]+f(i+b+s+1) | x<=i<=x+b}

按这个思路写完之后WA得生活不能自理,就又写了个暴力一点的想对拍,结果暴力还是WA= =

最后测试发现输出竟然还有负数,最后检查发现原来是数组开小了,2000的不够= =

然后把暴力代码数组扩成3000交上,居然就AC了= =卧槽没有TLE那我还写毛线啊,后来想了一下,数组开到4000才能过原来的代码。

至于写法如此暴力。。。应该是OJ没卡大数据

以下为暴力代码

/* ***********************************************

Author :axp

Created Time :2015/4/14 20:48:07

File Name :in.txt

************************************************ */

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <vector>

#include <queue>

#include <set>

#include <map>

#include <string>

#include <cmath>

#include <cstdlib>

#include <ctime>

using namespace std;

const int INF = 1<<30;

const int maxn = 3010;

int tim,sti,wait;

int arr[maxn];

int sum[maxn];

int dp[maxn];

int ans;

int f(int x)

{

if(dp[x]!=-1)

return dp[x];

if(x+sti>tim)

return dp[x]=0;

int re=INF;

for(int i=x;i<=tim;i++)

for(int j=0;j<sti;j++)

re=min(re,sum[i-1]-sum[x-1]+sum[i+j+wait]-sum[i+j]+f(i+j+wait+1));

return dp[x]=re;

}

int main()

{

//freopen("in.txt","r",stdin);

//freopen("out.txt","w",stdout);

while(scanf("%d%d%d",&sti,&wait,&tim)==3)

{

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

memset(arr,0,sizeof(arr));

for(int i=1;i<=tim;i++)

{

scanf("%d",&arr[i]);

}

for(int i=1;i<maxn;i++)

sum[i]=sum[i-1]+arr[i];

ans=f(1);

printf("%d\n",ans);

}

return 0;

}

以下为正常向代码

/* ***********************************************

Author :axp

Created Time :2015/4/14 20:48:07

File Name :in.txt

************************************************ */

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <vector>

#include <queue>

#include <set>

#include <map>

#include <string>

#include <cmath>

#include <cstdlib>

#include <ctime>

using namespace std;

const int INF = 1<<30;

const int maxn = 4010;

int tim,sti,wait;

int arr[maxn];

int sum[maxn];

int dp[maxn];

int ans;

int f(int x)

{

if(dp[x]!=-1)

return dp[x];

if(x+sti>tim)

return dp[x]=0;

int re=INF;

for(int i=x;i<x+sti;i++)
//防御x~i,等待时间为i+1~i+wait,f(i+wait+1)

{

re=min(re,sum[i+wait]-sum[i]+f(i+wait+1));

}

for(int i=x;i<=x+wait;i++)
//防御i+1~i+sti,等待时间为i+sti+1~i+sti+wait,f(i+sti+wait+1)

{

re=min(re,sum[i]-sum[x-1]+sum[i+wait+sti]-sum[i+sti]+f(i+wait+sti+1));

}

return dp[x]=re;

}

int main()

{

//freopen("in.txt","r",stdin);

//freopen("out.txt","w",stdout);

while(scanf("%d%d%d",&sti,&wait,&tim)==3)

{

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

memset(arr,0,sizeof(arr));

for(int i=1;i<=tim;i++)

{

scanf("%d",&arr[i]);

}

for(int i=1;i<maxn;i++)

sum[i]=sum[i-1]+arr[i];

ans=f(1);

printf("%d\n",ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐