现在的位置: 首页 > 综合 > 正文

UVA – 12063(关于倍数的dp转化成模运算)

2019年04月03日 ⁄ 综合 ⁄ 共 929字 ⁄ 字号 评论关闭
</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);
       }
   }
}



抱歉!评论已关闭.