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个设置仓库,一个仓库 ...
随机推荐
- Android开发之JNI(一)--HelloWorld及遇到的错误解析
Android开发之JNI(一)--HelloWorld及遇到的错误解析 1.NDK环境搭建 參考http://blog.csdn.net/xiaoliouc/article/details/8 ...
- 倍福TwinCAT(贝福Beckhoff)基础教程7.1 TwinCAT如何简单执行NC功能块 TC2
TC2的程序是在TC3的基础上稍作调整,只说明不同点,请先看TC3的. TC2中的一个原本是AXIS_REF类型变量被拆成了两个(PLCTONC_AXLESTRUCT和NCTOPLC_AXLESTRU ...
- Selenium webdriver Java 操作chrome 浏览器
Step1: 下载chromedriver. 下载路径: http://chromedriver.storage.googleapis.com/index.html 选择一个合适的下载即可.我下载的是 ...
- Centos系统信息及日志
1.确认内核版本: #uname -r #uname -a 2.确认发行版本: #cat /etc/redhat-release 3.查看系统载入的模块: #lsmod | grep XXX 载入一个 ...
- IE 页面不正常显示 错误脚本不报错 脚本调试相关
在开发时,有时自己做的页面上的JS有错误,但是IE浏览器并不报错,这个时候有可能是因为脚本调试被禁止了. 在Internet选项的高级里面有 两个禁止脚本调试选项,把他们去掉就行.
- PNP管理器简析--基于ReactOS0.33
CSDN上转悠了一圈发现关于PNP管理的文章不多.那就由我献个丑,记录自己对PNP管理器的看法. pnp管理器被描写叙述为向内核和应用程序提供关于设备拔插的通知,凭感觉,pnp管理器应该是个线程函数等 ...
- spring实现定时任务
今天在项目里需要实现一个定时任务,每隔3个小时将过滤的广告通过邮件上报给运营一次.考虑了一下,从实现的技术上可以有三种做法: 1.Java自带的java.util.Timer类,这个类允许调度一个ja ...
- iOS SDK具体解释之NSCopying协议
原创blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=contents 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn ...
- Atitit.收银机小票打印功能的设计 java php c#.net版本
Atitit.收银机小票打印功能的设计 java php c#.net版本 1. 1. 打印方式有4种:1 1.1. 1.1. 一是不经过任何修改,直接调用javascript中的window.pr ...
- 【转载】html标签语义化
Html语义化标签-语义化你的HTML标签和属性 1 语义化你的HTML标签和属性 1.1 <Hx> 1.2 <p> 1.3 <ul>.<ol>.& ...