您的位置:首页 > 其它

Light OJ 1145 Dice (I) (DP)

2016-02-12 16:34 387 查看
解析:设dp[i][j]为考虑前i个骰子,和为j的方案数。

状态转移时,dp[i][j+1....j+k+1]都要加上dp[i][j]。

直接转移的话复杂度为n*k*m。

借助树状数组区间增减的思想,对需要更改的区间的两端进行标记,这样复杂度为n*m。

[code]:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>

using namespace std;
typedef long long LL;
const int maxn = 15005;
const LL MOD = 1e8+7;

int n,k,m;
LL S[maxn],E[maxn];

int main(){
int i,j,cas,T;
scanf("%d",&cas);
for(T = 1;T <= cas;T++){
scanf("%d%d%d",&n,&k,&m);
LL tmp,a,b,c;
memset(S,0,sizeof(S));
memset(E,0,sizeof(E));
S[0] = 1;
for(i = 1;i <= n;i++){
for(j = 0;j < m;j++){
a = j+1,b = min(j+k+1,m+1);
E[a] = (E[a]+S[j])%MOD;
E[b] = ((E[b]-S[j])%MOD+MOD)%MOD;
}
tmp = 0;
for(j = 0;j <= m;j++){
tmp = (tmp+E[j])%MOD;
S[j] = tmp;E[j] = 0;
}
}

printf("Case %d: %lld\n",T,S[m]);
}

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