zoukankan      html  css  js  c++  java
  • poj 3590(dp 置换)

    题目的意思是对于序列1,2,...,n。要你给出一种字典序最小的置换使得经过X次后变成最初状态,且要求最小的X最大。

    通过理解置换的性质,问题可以等价于求x1,x2,..,xn 使得x1+x2+...+xk=n,且GLM(x1,x2,...,xn)最大。

    这个就用dp来做,首先求出100内的所有素数记录为prime[1] 到 prime[25]。

    状态:dp[i][j] 表示花费了i,且已经使用prime[1] 到 prime[j],的最大值。

    转移方程:因为要求最大值,单纯的用素数的积并不能得到最大值,最大值得形式是prime[1]^s1*prime[2]^s2*...*prime[25]^s25

    for(int i=1;i<=cnt;i++)
            {
                long long tmp[110];
                for(int j=0;j<=n;j++)
                    tmp[j]=dp[j];
                for(int k=1;mypow(saveprime[i],k)<=n;k++)
                {
                    long long tmpnum=mypow(saveprime[i],k);
                    for(int j=tmpnum;j<=n;j++)
                    {
                        dp[j]=max(tmp[j-tmpnum]*tmpnum,dp[j]);
                    }
                }
            }
    The shuffle Problem
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 1882   Accepted: 626

    Description

    Any case of shuffling of n cards can be described with a permutation of 1 to n. Thus there are totally n! cases of shuffling. Now suppose there are 5 cards, and a case of shuffle is <5, 3, 2, 1, 4>, then the shuffle will be:

    Before shuffling:1, 2, 3, 4, 5
    The 1st shuffle:5, 3, 2, 1, 4
    The 2nd shuffle:4, 2, 3, 5, 1
    The 3rd shuffle:1, 3, 2, 4, 5
    The 4th shuffle:5, 2, 3, 1, 4
    The 5th shuffle:4, 3, 2, 5, 1
    The 6th shuffle:1, 2, 3, 4, 5(the same as it is in the beginning)

    You'll find that after six shuffles, the cards' order returns the beginning. In fact, there is always a number m for any case of shuffling that the cards' order returns the beginning after m shuffles. Now your task is to find the shuffle with the largest m. If there is not only one, sort out the one with the smallest order.

    Input

    The first line of the input is an integer T which indicates the number of test cases. Each test case occupies a line, contains an integer n (1 ≤ n ≤ 100).

    Output

    Each test case takes a line, with an integer m in the head, following the case of shuffling.
     

    Sample Input

    2
    1
    5
    

    Sample Output

    1 1
    6 2 1 4 5 3


    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    int saveprime[30];
    long long dp[110];
    int saveans[110];
    int mypow(int x,int y)
    {
        int sum=1;
        for(int i=1;i<=y;i++)
            sum*=x;
        return sum;
    }
    
    int main()
    {
        int cnt=0;
        for(int i=2;i<=100;i++)
        {
            int flag=0;
            for(int j=2;j<i;j++)
            {
                if(i%j==0)
                {
                    flag=1;
                    break;
                }
            }
            if(flag==0)
            {
                saveprime[++cnt]=i;
            }
        }
    
        int T;
        cin>>T;
        while(T--)
        {
            int n;
            cin>>n;
            for(int i=0;i<=n;i++)
                dp[i]=1;
            for(int i=1;i<=cnt;i++)
            {
                long long tmp[110];
                for(int j=0;j<=n;j++)
                    tmp[j]=dp[j];
                for(int k=1;mypow(saveprime[i],k)<=n;k++)
                {
                    long long tmpnum=mypow(saveprime[i],k);
                    for(int j=tmpnum;j<=n;j++)
                    {
                        dp[j]=max(tmp[j-tmpnum]*tmpnum,dp[j]);
                    }
                }
            }
            cout<<dp[n];
            long long mx=dp[n];
            int anscnt=0;
            int anssum=0;
            for(int i=0;i<100;i++)
                saveans[i]=1;
            for(int i=1;i<=cnt;i++)
            {
                int sign=0;
                while(mx%saveprime[i]==0)
                {
                    saveans[anscnt] *= saveprime[i];
                    mx /= saveprime[i];
                    sign=1;
                }
                if(sign==1)
                {
                    anssum += saveans[ anscnt ];
                    anscnt++;
                }
            }
            sort(saveans,saveans+anscnt);
    
            //printf("
    ");
            //for(int i=0;i<anscnt;i++)
                //printf("%d ",saveans[i]);
            //printf("
    ");
            for(int i=1;i<=n-anssum;i++)
            {
                printf(" %d",i);
            }
            int pos=n-anssum;
            for(int i=0;i<anscnt;i++)
            {
                for(int j=2;j<=saveans[i];j++)
                    printf(" %d",pos+j);
                printf(" %d",pos+1);
                pos+=saveans[i];
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    codeforces 869E. The Untended Antiquity(二维树状数组,随机化)
    bzoj 3083: 遥远的国度(树上换根操作,树剖+询问整个子树)
    hdu 5534 Partial Tree(dp+降唯,好题)
    AtCoder Regular Contest 075 E
    hihocoder 1387 A Research on "The Hundred Family Surnames"(树,lca,求同一颜色的直径)
    hdu 5458 Stability(生成树,树链剖分,好题)
    推荐一套个人ui组件库
    回望2019,期盼2020
    如何从产品的角度对待自己的博客
    致一名迷茫的我
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/4896478.html
Copyright © 2011-2022 走看看