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=;i<=cnt;i++)
{
long long tmp[];
for(int j=;j<=n;j++)
tmp[j]=dp[j];
for(int k=;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]);
}
}
}
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[];
long long dp[];
int saveans[];
int mypow(int x,int y)
{
int sum=;
for(int i=;i<=y;i++)
sum*=x;
return sum;
} int main()
{
int cnt=;
for(int i=;i<=;i++)
{
int flag=;
for(int j=;j<i;j++)
{
if(i%j==)
{
flag=;
break;
}
}
if(flag==)
{
saveprime[++cnt]=i;
}
} int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
for(int i=;i<=n;i++)
dp[i]=;
for(int i=;i<=cnt;i++)
{
long long tmp[];
for(int j=;j<=n;j++)
tmp[j]=dp[j];
for(int k=;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=;
int anssum=;
for(int i=;i<;i++)
saveans[i]=;
for(int i=;i<=cnt;i++)
{
int sign=;
while(mx%saveprime[i]==)
{
saveans[anscnt] *= saveprime[i];
mx /= saveprime[i];
sign=;
}
if(sign==)
{
anssum += saveans[ anscnt ];
anscnt++;
}
}
sort(saveans,saveans+anscnt); //printf("\n");
//for(int i=0;i<anscnt;i++)
//printf("%d ",saveans[i]);
//printf("\n");
for(int i=;i<=n-anssum;i++)
{
printf(" %d",i);
}
int pos=n-anssum;
for(int i=;i<anscnt;i++)
{
for(int j=;j<=saveans[i];j++)
printf(" %d",pos+j);
printf(" %d",pos+);
pos+=saveans[i];
}
printf("\n");
}
return ;
}
poj 3590(dp 置换)的更多相关文章
- poj 3590 The shuffle Problem——DP+置换
题目:http://poj.org/problem?id=3590 bzoj 1025 的弱化版.大概一样的 dp . 输出方案的时候小的环靠前.不用担心 dp 时用 > 还是 >= 来转 ...
- POJ 3590 The shuffle Problem [置换群 DP]
传送门 $1A$太爽了 从此$Candy?$完全理解了这种$DP$做法 和bzoj1025类似,不过是求最大的公倍数,并输出一个字典序最小的方案 依旧枚举质因子和次数,不足的划分成1 输出方案从循环长 ...
- hdu 1513 && 1159 poj Palindrome (dp, 滚动数组, LCS)
题目 以前做过的一道题, 今天又加了一种方法 整理了一下..... 题意:给出一个字符串,问要将这个字符串变成回文串要添加最少几个字符. 方法一: 将该字符串与其反转求一次LCS,然后所求就是n减去 ...
- poj 1080 dp如同LCS问题
题目链接:http://poj.org/problem?id=1080 #include<cstdio> #include<cstring> #include<algor ...
- poj 1609 dp
题目链接:http://poj.org/problem?id=1609 #include <cstdio> #include <cstring> #include <io ...
- POJ 1037 DP
题目链接: http://poj.org/problem?id=1037 分析: 很有分量的一道DP题!!! (参考于:http://blog.csdn.net/sj13051180/article/ ...
- poj3270 && poj 1026(置换问题)
| 1 2 3 4 5 6 | | 3 6 5 1 4 2 | 在一个置换下,x1->x2,x2->x3,...,xn->x1, 每一个置换都可以唯一的分解为若干个不交的循环 如上面 ...
- Jury Compromise POJ - 1015 dp (标答有误)背包思想
题意:从 n个人里面找到m个人 每个人有两个值 d p 满足在abs(sum(d)-sum(p)) 最小的前提下sum(d)+sum(p)最大 思路:dp[i][j] i个人中 和 ...
- poj 1485 dp
转自:http://www.cnblogs.com/kuangbin/archive/2011/11/12/2246407.html [题目大意] 一条公路上有n个旅馆,选出其中k个设置仓库,一个仓库 ...
随机推荐
- Amixer 控制声音
amixer set Master XXXX 就可以直接控制主声卡属性 amixer set Master 20 #设置主声卡声音为 20 amixer set Master off #关闭主声卡(静 ...
- Java 1.7 ReentrantReadWriteLock源代码解析
因为本人水平与表达能力有限,有错误的地方欢迎交流与指正. 1 简单介绍 可重入读写锁时基于AQS实现的,典型的用法如JDK1.7中的演示样例: class RWDictionary { private ...
- IOS 应用程序路径
-- 获取资源文件目录 .app/下的图片,音频等资源文件 print("bundlePath" + NSBundle.mainBundle().bundlePath) //以下是 ...
- C#运用反射调用其他程序集中的代码
加载程序集 AssMedicalAdvice = Assembly.LoadFrom(Path.Combine(Environment.CurrentDirectory, "Inscript ...
- C语言-EOF和feof()判断文件结尾的区别
今天获取一个图片内容时, fopen("aaaaaa.png", "r"), 读取完文件头就停止了, 后来模式改为 "rb" 就可以了, 特 ...
- windows 2008 R2 x64安装oracle12c报INS-30131
问题描述:Window 2008 R2 x64安装Oracle12c报[INS-30131]执行安装程序验证所需的初始设置失败 解决方法:先在控制面板的“服务”,看SERVER服务是否启动,如果没有启 ...
- EntityFramework.SqlServer.dll 中发生 其他信息: 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: Named Pipes Provider, error: 40 - 无法打开到 SQL Server 的连接)
解决方案: 1.打开Sql server 管理配置器 或者在命令行输入:SQLServerManager10.msc 2.点击MSSQLSERVER的协议,在右侧的页面中选择TCP/IP协议启用 3. ...
- WSDL接口数据传递以及外网发布需要注意的地方
A系统传递数据给B系统 1.A创建asmx推送接口如下 using System; using System.Collection.Generic; using System.Data; using ...
- asp.net core mvc视频A:笔记6-1.应用发布与部署
显示:直接使用上节课的项目 一.使用vs发布应用 这里选择发布到文件夹,当然你可以选择其他的发布方式 部署模式:(我的VS里没有这个配置,不知道为啥...视频里有) 1.框架依赖:选择此模式,发布后需 ...
- ActivityGroup window bad token问题深入分析
如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456 ActivityGroup window bad token问题深入分析 近期帮别人调试一个webview ...