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时刻不一定要打怪兽)
但是每天那么长 ,数组开不了,但有循环!!!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }