HDU5291DPn堆糖果取出相等数目的糖果

26 篇文章 0 订阅
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
#define mod 1000000007
typedef long long lld;
int s[2010];
lld a[400010];
lld dp[2][400010];
void odd(int st,int num,lld add)
{
a[st]+=add;
a[st+num*2]-=add*2;
a[st+(num+num)*2]+=add;
}
void even(int st,int num,lld add)
{
a[st]+=add;
a[st+num*2]-=add;
a[st+(num+1)*2]-=add;
a[st+(num+num+1)*2]+=add;
}
#define base 40005
int main()
{
int cas;
scanf("%d",&cas);
for(int cc=1;cc<=cas;cc++)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&s[i]);
int T=0;
memset(dp,0,sizeof(dp));
int now=0;
int pre=1;
dp[now][base]=1;
for(int t=0;t<n;t++)
{
if(s[t] == 0)
continue;
int val=s[t];
T+=val;
now^=1;
pre^=1;
for(int i=base-T-4;i<=base+T+4;i++)
dp[now][i]=a[i]=0;
for(int i=base-T-4;i<=base+T+4;i++)
{
if(dp[pre][i] == 0)
continue;
int num;
num=val/2+1;
odd(i-num*2,num,dp[pre][i]);
num=(val+1)/2;
even(i-num*2-1,num,dp[pre][i]);
}
lld tot,v;
tot=v=0;
for(int i=base-T-4;i<=base+T+4;i+=2)
{
a[i]=(a[i]%mod+mod)%mod;
tot=(tot+v)%mod;
dp[now][i]=tot;
v=(v+a[i])%mod;
}
tot=v=0;
for(int i=base-T-4+1;i<=base+T+4;i+=2)
{
a[i]=(a[i]%mod+mod)%mod;
tot=(tot+v)%mod;
dp[now][i]=tot;
v=(v+a[i])%mod;
}
}
printf("%d\n",(int)dp[now][base]);
}
return 0;
}
/*
1
2
2 2


 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值