hdu 5691 Sitting in Line 状压dp
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5691
题解:
和tsp用的状压差不多,就是固定了一些访问顺序。
dp[i][j]表示前cnt个点中布满状态i且最后一个为j的状态的最大乘积和。
则有dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+a[j]*a[k])。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn = ;
const int INF = 2e9;
int dp[ << ][];
int cnt[ << ];
int a[maxn], p[maxn],f[maxn];
int n; void pre() {
for (int i = ; i < ( << ); i++) {
cnt[i] = ;
for (int j = ; j < ; j++) {
if (i&( << j)) cnt[i]++;
}
}
} void init() {
for (int i = ; i < ( << n); i++) {
for (int j = ; j <= n; j++) {
dp[i][j] = -INF;
}
}
memset(f, -, sizeof(f));
} int main() {
pre();
int tc,kase=;
scanf("%d", &tc);
while (tc--) {
scanf("%d", &n);
init();
for (int i = ; i < n; i++) {
scanf("%d%d", a + i, p + i);
if (p[i] != -) f[p[i]] = i;
}
a[n] = ; p[n] = n;
dp[][n] = ;
for (int i = ; i < ( << n); i++) {
int sum = cnt[i];
for (int j = ; j <= n; j++) {
if ((i&( << j)) == &&j!=n) continue;
//被限制的点:
if (f[sum] != -) {
if ((i&( << f[sum])) == ) {
dp[i | ( << f[sum])][f[sum]] =
max(dp[i | ( << f[sum])][f[sum]], dp[i][j]+a[j]*a[f[sum]]);
}
}
else {
//可以自由移动的点
for (int k = ; k < n; k++) {
if (i&( << k)) continue;
if (p[k] ==-) {
dp[i | ( << k)][k] = max(dp[i | ( << k)][k], dp[i][j] + a[j] * a[k]);
}
}
}
}
}
int ans = -INF;
for (int j = ; j < n; j++) ans = max(ans, dp[( << n) - ][j]);
printf("Case #%d:\n", ++kase);
printf("%d\n", ans);
}
return ;
}
再一发:
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=10000000000000000LL;
const double eps=1e-; const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=; LL dp[<<maxn][maxn];
LL arr[maxn];
int pos[maxn],mp[maxn];
int sumv[<<maxn];
int n; void pre(){
clr(sumv,);
for(int i=;i<(<<maxn);i++){
for(int j=;j<maxn;j++){
if(i&(<<j)){
sumv[i]++;
}
}
}
} void init(){
clr(mp,-);
} int main() {
pre();
int tc,kase=;
scf("%d",&tc);
while(tc--){
scf("%d",&n);
init();
rep(i,,n){
scf("%lld%d",&arr[i],&pos[i]);
if(pos[i]>=) mp[pos[i]]=i;
} rep(i,,(<<maxn)) rep(j,,maxn) dp[i][j]=-INFL;
if(mp[]>=){
dp[<<mp[]][mp[]]=;
}else{
for(int i=;i<n;i++){
if(pos[i]>=) continue;
dp[<<i][i]=;
}
} rep(i,,(<<n)){
rep(j,,n){
if(!(i&(<<j))) continue;
if(mp[sumv[i]-]>=&&mp[sumv[i]-]!=j) continue;
rep(k,,n){
if(k==j||!(i&(<<k))) continue;
if(mp[sumv[i^(<<j)]-]>=&&mp[sumv[i^(<<j)]-]!=k) continue;
dp[i][j]=max(dp[i][j],dp[i^(<<j)][k]+arr[k]*arr[j]);
}
}
} LL ans=-INFL;
rep(i,,n) ans=max(ans,dp[(<<n)-][i]);
prf("Case #%d:\n",++kase);
prf("%lld\n",ans); }
return ;
} //end-----------------------------------------------------------------------
hdu 5691 Sitting in Line 状压dp的更多相关文章
- hdu 5691 Sitting in line 状压动归
在本题中,n<=16n<=16n<=16, 不难想到可以将所选数字的编号进行状态压缩. 定义状态 dp[S][j]dp[S][j]dp[S][j],其中 SSS 代表当前所选出的所有 ...
- hdu 5691 Sitting in Line
传送门 Sitting in Line Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/O ...
- HDU 6149 Valley Numer II 状压DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意:中文题目 解法:状压DP,dp[i][j]代表前i个低点,当前高点状态为j的方案数,然后枚 ...
- HDU 1074 Doing Homework【状压DP】
Doing Homework Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he ...
- HDU 5434 Peace small elephant 状压dp+矩阵快速幂
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: ...
- HDU 1074 Doing Homework(状压DP)
第一次写博客ORZ…… http://acm.split.hdu.edu.cn/showproblem.php?pid=1074 http://acm.hdu.edu.cn/showproblem.p ...
- HDU - 4284 Travel(floyd+状压dp)
Travel PP loves travel. Her dream is to travel around country A which consists of N cities and M roa ...
- HDU 4906 Our happy ending (状压DP)
HDU 4906 Our happy ending pid=4906" style="">题目链接 题意:给定n个数字,每一个数字能够是0-l,要选当中一些数字.然 ...
- HDU 1074 Doing Homework (状压dp)
题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...
随机推荐
- POJ C++程序设计 编程题#1 编程作业—运算符重载
编程题 #2 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 下面的MyIn ...
- WWDC————苹果全球开发者大会
WWDC:Apple Worldwide Developers Conference(苹果全球开发者)的简称,每年定期由苹果公司(Apple Inc.)在美国举办.大会主要的目的是让苹果公司向研发者们 ...
- Dockpanel的控件加载问题
1. 正确加载模式:panel.ControlContainer.Controls.Add(control); 如果用panel.Controls.Add(control);则可能出现模块发生位移问题 ...
- 获取屏幕分辨率(C/C++)
C/C++获取屏幕分辨率的方法 int main(int argc, char* argv[]) { // 需要添加头文件: // #include <Windows.h> system( ...
- qemu-kvm简单使用
qemu-kvm主要有以下几个选项: -snapshot: 创建快照 -m: 指定内存大小 -smp: 指定处理器个数 -cpu: 指定CPU类型 -name: 设置虚拟机名称 -vnc: 使用vnc ...
- 在PyQt中直接使用ui文件并加载qrc资源文件
1. 用Qt设计师创建一个包含qrc资源文件的ui文件 2.打开cmd使用以下命令把qrc资源文件转换成十六进制的py文件 pyrcc4 -o C:\res.py C:\res.qrc pyrcc4 ...
- 生产WCF客户端类文件的命令格式
生产WCF客户端类文件的命令格式: svcutil.exe net.tcp://127.0.0.1:8732/ChromaMI.Remote.ConfigService/RemoteConfigSer ...
- 共享内存 share pool (2):BUCKET /FREE LISTS /RESERVED FREE LISTS /UNPINNED RECREATABLE CHUNKS (lru first)
相关概念 BUCKET :每个bucket上挂有一个 chunk list.同一个BUCKET中的chunk在物理地址上是不一定相邻的 FREE LISTS:按bucket划分,共有255个,buck ...
- Eclipse 4.6 Neon, could not create the java virtual machine
下了eclipse 4.6,打开报错:could not create the java virtual machine. a fatal exception has occurred. 命令行用 e ...
- 【Cocoa】 Initializing View Instances Created in Interface Builder
Initializing View Instances Created in Interface Builder View instances that are created in Interfac ...