hdu 4669 Mutiples on a circle(按位DP)

来源:互联网 发布:国民女团网络电影 编辑:程序博客网 时间:2024/05/16 12:49

按位dp,将原来的n个数扩展为 2*n-1 个数

#include <cstdio>#include <cmath>#include <algorithm>using namespace std;const int MAXN = 50005;const int MAXK = 205;int num[MAXN*2], nwei[MAXN*2], dp[2][MAXK], swei[MAXN*2];int n, k;int ten[MAXN*4];void getwei(int i){int nm = num[i], res = 0;while (nm){++res; nm /= 10;}nwei[i] = res;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endiften[0] = 1;while (scanf("%d%d", &n, &k) != EOF){int nn = 2*n -1;for (int i = 1; i<= n; ++i){scanf("%d", num+i);getwei(i);}for (int i = n+1; i<= nn; ++i){num[i] = num[i-n];nwei[i] = nwei[i-n];}for (int i = 1; i<= 4*n; ++i){ten[i] = ten[i-1]*10%k;}memset(dp, 0, sizeof dp);int sum = 0, nt = 0, res = 0;for (int i = n; i> 0; --i){sum = (num[i]*ten[nt] + sum)%k;nt += nwei[i];++dp[0][sum];}res += dp[0][0];--dp[0][sum];for (int i = 0; i< k; ++i){dp[1][(i*ten[nwei[n+1]]+num[n+1])%k] += dp[0][i];}int cur = 1;for (int i = n+1; i<= nn; ++i, cur=1-cur){dp[cur][num[i]%k]++;res += dp[cur][0];sum = ((sum - ten[(nt-nwei[i-n])]*num[i-n]%k + k)*ten[nwei[i]] + num[i])%k;nt = nt-nwei[i-n]+nwei[i];--dp[cur][sum];memset(dp[1-cur], 0, 4*MAXK);for (int j = 0; j< k; ++j){dp[1-cur][(j*ten[nwei[i+1]]+num[i+1])%k] += dp[cur][j];}}printf("%d\n", res);}return 0;}



0 0
原创粉丝点击