hdu3851(dp+区间范围很大且有循环的处理方法)

题意:有一只怪兽,在白天攻击一次能损失它pd点血,晚上攻击则损失它pn点血,每次攻击的间隔为t,每天的白天时间与晚上时间分别为t1i, t2i,问N天内最多攻击它多少血。n <= 1000, t <= 100

题目大意:大炮打怪兽!!大炮发一次炮后T小时不能工作。如果怪兽白天遭打的伤害值是PD,晚上遭打的伤害值是PN。这个奇怪的城市有个奇怪的时间,每天白天的时间和晚上的时间长度都不同。求,在N天里,打怪兽的最大伤害值是多少。

dp[i]=max(dp[i-1],dp[i-t]+num[i]);  dp[i]表示前i个时候最大分数(i时刻不一定要打怪兽)

但是每天那么长 ,数组开不了,但有循环!!!

#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#define tree int o,int l,int r
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define lo o<<1
#define ro o<<1|1
#define pb push_back
#define mp make_pair
#define ULL unsigned long long
#define LL long long
#define inf 0x7fffffff
#define eps 1e-7
#define N 209
using namespace std;
int m,n,T,t,pn,pd;
LL d[2][N];
void fun(int pd)
{
    int cur=0,last=1;
    d[cur][0]=d[last][t];
    for(int i=1; i<=t&&i<=m; i++)
        {
            d[cur][i]=max(d[cur][i-1],d[last][i]+pd);
        }
    if(m>=t)
    {
        for(int i=t,j=m; i>=1; i--,j--)
        {
            int s=j%t;
            if(!s)s=t;
            d[last][i]=d[cur][s]+(LL)pd*((j-s)/t);
        }
    }
    else
    {
        for(int i=1,j=t-(t-m)+1,k=1; i<=t; i++,j++)
        {
            if(j>t)
                d[last][i]=d[cur][k++];
            else
                d[last][i]=d[last][j];
        }
    }
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("ex.in","r",stdin);
#endif
    int ncase=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d",&n,&t,&pd,&pn);
        memset(d,0,sizeof(d));
        int cur=0,last=1;
        for (int i=0; i<n; ++i )
        {
            scanf("%d",&m);
            fun(pd);
            scanf("%d",&m);
            fun(pn);
        }
        printf("Case %d: %I64d\n",++ncase,d[last][t]);
    }
    return 0;
}
View Code

 

posted @ 2013-10-12 21:07  baoff  阅读(161)  评论(0编辑  收藏  举报