dp+内存压缩+前缀和+离线处理
dp[i][j] 表示 n=i,k=j 时的答案。
pre[i][j] 表示 dp[i][j] 的前缀和。
转移方程:
dp[i][j]=pre[i-1][j]-(j-i>=0?pre[i-1][j-i]:0)
#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
long long dp[2][20020],pre[2][20020],ans[10010];
int n[10010],k[10010];
int main()
{
int T,i,j,t;
scanf("%d",&T);
for(i=0;i<T;i++)
{
scanf("%d%d",&n[i],&k[i]);
}
memset(dp,0,sizeof(dp));
memset(pre,0,sizeof(pre));
dp[1][0]=1;
for(j=0;j<=20000;j++)
pre[1][j]=1;
for(i=2;i<=1000;i++)
{
dp[i&1][0]=pre[i&1][0]=1;
for(j=1;j<=20000;j++)
{
if(j<=i*(i-1)/2)
dp[i&1][j]=(pre[i&1^1][j]-(j-i>=0?pre[i&1^1][j-i]:0)+mod)%mod;
pre[i&1][j]=(pre[i&1][j-1]+dp[i&1][j])%mod;
}
for(j=0;j<T;j++)
{
if(n[j]==i)
ans[j]=dp[i&1][k[j]];
}
}
for(i=0;i<T;i++)
printf("%lld\n",ans[i]);
}

本文介绍了一种结合动态规划、内存压缩、前缀和及离线处理技术的算法实现方案。通过预计算前缀和来简化状态转移方程,有效降低计算复杂度。适用于求解特定类型的问题,例如组合计数等。
2382

被折叠的 条评论
为什么被折叠?



