HDU 5330 Route Statistics

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5330

题意:给出n个长度为m,并且只有012组成的串,两个串的距离为每一位相差的绝对值相加,问距离为0-2m的对数分别有几对

参考:http://blog.csdn.net/glqac/article/details/48971143

最后计算答案的时候,距离为0的话只能跟相同串的互相选择,不为零就是直接相乘

最后所有对数都算了两遍,所以要除2

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int N=2e5+5;
int cnt[N],dp[2][N][25];
int f[20];
char s[20];
long long ans[25];
int now=0,pre=1;
int main()
{
    f[0]=1;
    for(int i=1;i<=11;i++)
        f[i]=f[i-1]*3;
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            int sum=0;
            for(int j=0;j<m;j++)
                sum=sum*3+s[j]-'0';
            cnt[sum]++;
        }
        memset(dp[now],0,sizeof(dp[now]));
        for(int i=0;i<f[m];i++)
            dp[now][i][0]=cnt[i];
        for(int i=0;i<m;i++)
        {
            swap(now,pre);
            memset(dp[now],0,sizeof(dp[now]));
            for(int j=0;j<f[m];j++)
                for(int k=0;k<=2*m;k++)
                if (dp[pre][j][k])
            {
                int tem=j/f[i]%3;
                for(int l=0;l<=2;l++)
                {
                    int t=j-(tem-l)*f[i];
                    dp[now][t][k+abs(tem-l)]+=dp[pre][j][k];
                }
            }
        }
        memset(ans,0,sizeof(ans));
        for(int i=0;i<f[m];i++)
        {
            if (!cnt[i]) continue;
            ans[0]+=1LL*cnt[i]*(cnt[i]-1);//dp[now][i][0]==cnt[i]
            for(int j=1;j<=2*m;j++)
                ans[j]+=1LL*cnt[i]*dp[now][i][j];
        }
        for(int i=0;i<=2*m;i++)
            printf("%lld
",ans[i]/2LL);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/bk-201/p/7476758.html