</pre>以状态d(i,j,k)代表第前i位用j个一能组成所有对K取模余数为k的数状态转移即该位置为1还是0<p>还有一点要说明 最后结果不是d(n-1,n/2-1,K-yu[n] (yu[n]为2^(n-1)对K取模后的值) ) 而是d(n-1,n/2-1,(K-yu[n])%K);</p><p><pre name="code" class="html">#include <cstdio>
#include <vector>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 66;
const int maxk = 105;
long long d[maxn][maxn][maxk];
bool vis[maxn][maxn][maxk];
int yu[maxn],n,K;
long long dp(int i,int j,int k){
if(vis[i][j][k]) return d[i][j][k];
vis[i][j][k]=true;
if(i==0){
if(j!=0) return d[i][j][k]=0;
return d[i][j][k] = (k%K==0 ? 1 : 0);
}
d[i][j][k]=dp(i-1,j,k);
if(j>0) d[i][j][k]=d[i][j][k]+dp(i-1,j-1,(K+k-yu[i])%K);
return d[i][j][k];
}
int main()
{
int T;
scanf("%d",&T);
int kase=1;
while(T--){
scanf("%d %d",&n,&K);
printf("Case %d: ",kase++);
if(n&1||K==0) printf("0\n");
else{
yu[1]=1;
for(int i=2;i<=n;i++){
yu[i]=(yu[i-1]*2)%K;
}
memset(vis,false,sizeof(vis));
long long temp = dp(n-1,n/2-1,(K-yu[n])%K );
printf("%lld\n",temp);
}
}
}
UVA - 12063(关于倍数的dp转化成模运算)
最新推荐文章于 2020-06-22 17:38:03 发布