Hdu4623: Crime mathematical optimization DP

Source: Internet
Author: User

Anshan warm-up match, also the original question of multiple schools last year

Question:

Evaluate the number of adjacent numbers in the order of N numbers and perform the modulo operation

The idea at that time was to press DP .. DP [I] [State] State to record whether a certain number is removed in binary format. I indicates the number at the end of the current sequence.

Then GCD status is transferred

But n is 28, and there are hundreds of millions of States .. It cannot be done ..

After I came back, I found that I could use the mathematical method to optimize the problem. So after half a day, I finally got the AC.

First, in this question:

Whether two numbers are mutually correlated is only with their prime factor. Therefore, the numbers with the same prime factor are equivalent, which is called the equivalence class of this problem.

It is easy to find these equivalence classes and obtain the number of classes ..

Therefore, you only need to process these equivalence classes, and then multiply each equivalence class by the number of permutation numbers to get the answer.

However, when there is a quantity, binary compression cannot be used. Hash should be used for compression.

After research, we will find that the hash pressure is similar to the binary pressure, except that the base number is changed from (1 + 1) ^ n to (Num [1] + 1) * (Num [2] + 1 ).... it is also easy to understand.

After processing these statuses, we found that there are only 5600000 states for n = 28, and the number of equivalence classes is 17, so the complexity is 17*5600000.

It's time for MLE. Since the modulo Max is 30000, the array is changed to short, and the intermediate result int is used to prevent overflow, so the memory is no longer exposed.

Then the time limit is 30 s. I thought it was okay, and the result was no longer ..

Then I thought for a while and found that the numbers 17, 19, and 23 are mutually compatible with any other number .. So they are equivalent to 1.

After this optimization, the complexity is reduced to about 14*1800000.

8800 Ms ac...

The Code is as follows:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int prime[]={2,3,5,7,11,13,17,19,23};const int np=9;int state[30];int g[300][300];int vi[300];int num[30];int base[30];short dp[19][2000000];bool ok[29];int n,m,ns,st;void ini(){    scanf("%d%d",&n,&m);    memset(g,0,sizeof(g));    memset(vi,0,sizeof(vi));    memset(num,0,sizeof(num));    ns=0;    state[++ns]=0;    num[ns]=1;    for(int i=2;i<=n;i++)    {        st=0;        if(ok[i])        {            num[1]++;            continue;        }        for(int j=0;j<np;j++)        {            if(i%prime[j]==0)            {                st|=(1<<j);            }        }        if(!vi[st])        {            state[++ns]=st;            num[ns]=1;            vi[st]=ns;        }        else        {            num[vi[st]]++;        }    }    for(int i=1;i<=ns;i++)    {        for(int j=1;j<=ns;j++)        {            if((state[i]&state[j])==0)                g[i][j]=1;        }    }    base[1]=1;    st=0;    for(int i=1;i<=ns;i++)    {        base[i+1]=base[i]*(num[i]+1);        st+=base[i]*num[i];    }}int getnum(int i,int x){    int res=(x%base[i+1])/(base[i]);    return res;}int getstate(int i,int num){    return num*base[i];}void dfs(int t,int x){    if(t==0)    {        dp[x][0]=1;        return ;    }    if(dp[x][t]!=-1)        return;    dp[x][t]=0;    for(int i=1;i<=ns;i++)    {        if(g[x][i]&&getnum(i,t)>=1)        {            dfs(t-base[i],i);            dp[x][t]=((int)dp[x][t]+dp[i][t-base[i]])%m;        }    }    return;}int main(){    #ifndef ONLINE_JUDGE        freopen("in.txt","r",stdin);    #endif // ONLINE_JUDGE    int T;    scanf("%d",&T);    memset(ok,0,sizeof(ok));    ok[17]=1;    ok[19]=1;    ok[23]=1;    while(T--)    {        ini();        memset(dp,-1,sizeof(dp));        int ans=0;        for(int i=1;i<=ns;i++)        {            dfs(st-base[i],i);            ans=((int)ans+dp[i][st-base[i]])%m;        }        for(int i=1;i<=ns;i++)        {            while(num[i]>1)            {                ans=((int)ans*num[i])%m;                num[i]--;            }        }        printf("%d\n",ans);    }}

 

Hdu4623: Crime mathematical optimization DP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.