HDU 4640 状态压缩DP 未写完
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4640
解题思路:
首先用一个简单的2^n*n的dp可以求出一个人访问一个给定状态的最小花费,因为这i个人是等价的,所以用dp[i][mask]表示i个人跑完mask这个状态的最小花费,所以首先枚举集合mask,对于dp[i][mask],枚举mask的子集v,dp[i][mask]可以由dp[1][v],dp[i-1][mask^v]转移过来,注意这里用来合并的集合是不能有重复的,这个类似背包……这样就可以算出对于每个状态三个人访问完的最小花费,之后对于给定的需要访问的状态,枚举包含这个给定状态的集合更新答案就可以了……注意对于刚开始给定的图是不能floyd的,因为要求任意两个人的路径不能相交……还有就是1这个节点可以每个人经过多次,这里需要特殊处理一下……
以上摘自杭电的解题报告
下面是我还未写完的代码,我还不会做这个题,所以···还得想想····以后会改好的
#include <cstdio>
#include <queue>
using namespace std;
#define N (1<<17)+5
#define INF 100000000
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b int n,status; //人数,学妹位置的状态
int d[N][],dp1[N],dp2[N];
bool in[N][];
int edge[][];
queue<int> qu;
void initScan()
{
int m;
scanf("%d%d",&n,&m);
for(int i=; i<n; ++i)
{
for(int j=; j<n; ++j)
{
if(i == j) edge[i][j] = ;
else edge[i][j] = INF;
}
}
while(m--)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
--u,--v;
edge[u][v] = min(edge[u][v],c);
edge[v][u] = edge[u][v];
}
int k;
status = ;
scanf("%d",&k);
while(k--)
{
int sis;
scanf("%d",&sis);
status |= (<<(sis-));
}
status >>= ;
}
void bfs()
{
memset(in,,sizeof(in));
memset(d,0x3f,sizeof(d));
qu.push();//先城市
qu.push();//后状态
d[][] = ;
in[][] = true;
while(!qu.empty())
{
int i = qu.front();//状态
qu.pop();
int j = qu.front();//城市
qu.pop();
in[i][j] = false;
for(int k=; k<n; ++k)
{
int w = i |( << k);
if(d[w][k] > d[i][j] + edge[j][k] )
{
d[w][k] = d[i][j] + edge[j][k];
if(!d[w][k])
{
qu.push(k);
qu.push(w);
in[w][k] = ;
}
}
}
}
}
void DP1()
{
memset(dp1,0x3f,sizeof(dp1));
for(int i=; i<(<<n); ++i)
{
for(int j=; j<n; ++j)
dp1[i>>] = min(dp1[i>>],d[i][j]);
}
}
void DP2()
{
for(int i=; i<(<<n); ++i)
{
int j = i;
while(j)
{
j=(j-)&i;
dp2[i] = min( dp2[i],max(dp2[j],dp2[i^j]) );
}
}
}
int solve()
{
int ans = INF;
int j = status;
while(j)
{
j=(j-)&status;
ans = min( ans,max(dp2[j],dp1[status^j]) );
ans = min(ans,max(dp2[status^j],dp1[j]) );
}
return ans;
} int main()
{
freopen("in.cpp","r",stdin);
freopen("myout.cpp","w",stdout);
int t;
scanf("%d",&t);
for(int ser=; ser<=t; ++ser)
{
initScan();
bfs();
DP1();
for(int i=; i<(<<n); ++i)
printf("d[%d] = %d\n",i,dp1[i]);
DP2();
int ans = solve();
printf("Case %d: ",ser);
if(ans == INF) printf("-1\n");
else printf("%d\n",ans);
}
return ;
}
下面是标程1:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
#define N 101
int sta;
int d[N][N];
int dp[ << ][];
bool in[ << ][];
int dp_1[ << ], dp_2[ << ];
int main() {
int t, cas = ;
scanf(" %d", &t);
while (t--) {
int n, m;
scanf(" %d %d", &n, &m);
// if(cas==13) printf("%d %d\n",n,m);
memset(d, 0x3f, sizeof(d));
for (int i = ; i < m; i++) {
int x, y, s;
scanf(" %d %d %d", &x, &y, &s);
// if(cas==13) printf("%d %d %d\n",x,y,s);
d[x][y] = min(d[x][y], s);
d[y][x] = d[x][y];
} queue<int> qu;
qu.push();
qu.push();
memset(in, , sizeof(in));
memset(dp, 0x3f, sizeof(dp));
dp[][] = ;
in[][] = true; while (!qu.empty()) {
int s_sta = qu.front();
qu.pop();
int s = qu.front() + ;
qu.pop();
in[s_sta][s - ] = false; for (int i = ; i < n; i++) {
int to = i + ;
int t_sta = ( << i) | s_sta;
if (to == )
continue;
if (dp[t_sta][to - ] > dp[s_sta][s - ] + d[s][to]) {
dp[t_sta][to - ] = dp[s_sta][s - ] + d[s][to];
if (!in[t_sta][to - ]) {
in[t_sta][to - ] = ;
qu.push(t_sta);
qu.push(to - );
}
}
}
} memset(dp_1, 0x3f, sizeof(dp_1));
for (int i = ; i < ( << n); i++) {
for (int j = ; j < n; j++) {
dp_1[i >> ] = min(dp_1[i >> ], dp[i][j]);
}
} int tar = , k;
scanf(" %d", &k);
// if(cas==13) printf("%d\n",k);
while (k--) {
int x;
scanf(" %d", &x);
// if(cas==13) printf("%d ",x);
tar |= ( << (x - ));
}
int ans = INF;
int tol = ( << (n - )) - ;
memcpy(dp_2, dp_1, sizeof(dp_1));
for (int i = ; i < ( << (n - )); i++) {
for (int j = i; j; j = (j - ) & i) {
dp_2[i] = min(dp_2[i], max(dp_1[j], dp_1[i ^ j]));
}
}
for (int i = tol; i; i--) {
for (int j = i;; j = (j - ) & i) {
if ((i & tar) == tar) {
ans = min(ans, max(dp_1[j], dp_2[i ^ j]));
}
if (j == )
break;
}
}
if (ans == INF)
ans = -;
printf("Case %d: %d\n", cas++, ans);
}
return ;
}
标程2:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef __int64 lld;
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define maxn 20
struct Edge
{
int v,s,next;
}edge[];
int head[maxn];
int pos;
void insert(int x,int y,int s)
{
edge[pos].v=y;
edge[pos].s=s;
edge[pos].next=head[x];
head[x]=pos++;
}
int dis[<<][];
bool vis[<<][];
pair<int,int>queue[];
int rear,front;
int maxQ=;
int dp[<<];
int f[<<];
int main()
{
// freopen("input.txt","r",stdin);
int cas;
scanf("%d",&cas);
for(int cc=;cc<=cas;cc++)
{
int n,m;
scanf("%d %d",&n,&m);
memset(head,,sizeof(head));
pos=;
while(m--)
{
int x,y,s;
scanf("%d %d %d",&x,&y,&s);
insert(x,y,s);
insert(y,x,s);
}
memset(dis,-,sizeof(dis));
memset(vis,false,sizeof(vis));
rear=front=;
for(int i=head[];i;i=edge[i].next)
{
int v=edge[i].v;
v-=;
if(dis[<<v][v] == - || edge[i].s < dis[<<v][v])
{
dis[<<v][v]=edge[i].s;
if(!vis[<<v][v])
{
vis[<<v][v]=true;
queue[front++]=mp(<<v,v);
}
}
}
while(rear != front)
{
int mask=queue[rear].X;
int u=queue[rear].Y;
rear++;
if(rear == maxQ)
rear=;
vis[mask][u]=false;
for(int i=head[u+];i;i=edge[i].next)
{
int v=edge[i].v;
if(v == )
continue;
v-=;
int next=mask|(<<v);
if(dis[next][v] == - || dis[mask][u]+edge[i].s < dis[next][v])
{
dis[next][v]=dis[mask][u]+edge[i].s;
if(!vis[next][v])
{
vis[next][v]=true;
queue[front++]=mp(next,v);
if(front == maxQ)
front=;
}
}
}
}
memset(dp,-,sizeof(dp));
dp[]=;
int T=<<(n-);
for(int mask=;mask<T;mask++)
for(int i=;i<n-;i++)
{
if(dis[mask][i] == -)
continue;
if(dp[mask] == - || dis[mask][i] < dp[mask])
dp[mask]=dis[mask][i];
}
for(int mask=;mask<T;mask++)
f[mask]=dp[mask];
for(int k=;k<;k++)
{
for(int u=T-;u>;u--)
for(int v1=u;;v1=(v1-)&u)
{
int v2=u^v1;
if(dp[v1] == - || f[v2] == -)
{
if(v1 == )
break;
continue;
}
if(dp[u] == - || max(dp[v1],f[v2]) < dp[u])
dp[u]=max(dp[v1],f[v2]);
if(v1 == )
break;
}
}
int Q;
scanf("%d",&Q);
int mask=;
while(Q--)
{
int x;
scanf("%d",&x);
x-=;
mask|=<<x;
}
int ans=-;
for(int u=;u<T;u++)
if((u&mask) == mask)
{
if(dp[u] == -)
continue;
if(ans == - || dp[u] < ans)
ans=dp[u];
}
printf("Case %d: %d\n",cc,ans);
}
return ;
}
HDU 4640 状态压缩DP 未写完的更多相关文章
- HDU 1074 (状态压缩DP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...
- HDU 3341 状态压缩DP+AC自动机
题目大意: 调整基因的顺序,希望使得最后得到的基因包含有最多的匹配串基因,使得所能达到的智商最高 这里很明显要用状态压缩当前AC自动机上点使用了基因的情况所能达到的最优状态 我最开始对于状态的保存是, ...
- hdu 4284 状态压缩dp
题意: 有N 个点的无向图,要去其中 h个地点做事,做事需要先办理护照,之后可以挣一定数量的钱,知道了一开始有的总钱数,和 一些城市之间 道路的花费,问可不可以在 指定的 h 个城 ...
- hdu 2167 状态压缩dp
/* 状态转移方程:dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]); */ #include<stdio.h> #include<string ...
- HDU 4856 (状态压缩DP+TSP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4856 题目大意:有一个迷宫.迷宫里有些隧道,每个隧道有起点和终点,在隧道里不耗时.出隧道就耗时,你的 ...
- hdu 1074(状态压缩dp+记录路径)
题意:给了n个家庭作业,然后给了每个家庭作业的完成期限和花费的实践,如果完成时间超过了期限,那么就要扣除分数,然后让你找出一个最优方案使扣除的分数最少,当存在多种方案时,输出字典序最小的那种,因为题意 ...
- HDU 4906 状态压缩dp
Our happy ending Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- 2016"百度之星" - 初赛(Astar Round2A)1002 / HDU 5691 状态压缩DP
Sitting in Line Problem Description 度度熊是他同时代中最伟大的数学家,一切数字都要听命于他.现在,又到了度度熊和他的数字仆人们玩排排坐游戏的时候了.游戏的规则十 ...
- HDU 5067 (状态压缩DP+TSP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5067 题目大意:蓝翔挖掘机挖石子.把地图上所有石子都运回起点,问最少耗时. 解题思路: 首先得YY出 ...
随机推荐
- Codeforces 447D - DZY Loves Modification
447D - DZY Loves Modification 思路:将行和列分开考虑.用优先队列,计算出行操作i次的幸福值r[i],再计算出列操作i次的幸福值c[i].然后将行取i次操作和列取k-i次操 ...
- 雷林鹏分享:C# 异常处理
C# 异常处理 异常是在程序执行期间出现的问题.C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零. 异常提供了一种把程序控制权从某个部分转移到另一个部分的方式.C# 异常处理时建立 ...
- 缓存地图 ArcGIS ——Local compact and exploded tile cache layer for WPF API
ArcGISArcGIS 主页 特色 合约 图库 地图 组 帮助 我的内容 我的组织 登录 我的个人资料 帮助 管理员指南 登出 0 搜索全部内容 搜索地图 搜索图层 搜索应用程序 搜索工具 搜索 ...
- android--------ListView和ExpandableListView的侧滑删除操作
本案例主要实现了ListView和ExpandableListView的侧滑删除操作功能 效果图: ListView的Adapter类 private class SlideAdapter exten ...
- C++&C#外挂(内存修改)
大学时候因为主修C#语言(当然现在做的是javaweb开发),那时在网上学了用C#做外挂的教程,外挂嘛,大家都懂的.这里只是低级的修改内存,不涉及到截获数据包.如果是欺骗服务器,修改服务器数据,那就难 ...
- 21 模块(collections,time,random,os,sys)
关于模块importfrom xxx import xxx2. Collections1. Counter 计数器2. 栈: 先进后出.队列:先进先出deque:双向队列3. defaultdict ...
- Gluttony CodeForces - 892D (构造,思维)
题面: You are given an array a with n distinct integers. Construct an array b by permuting a such that ...
- MQTT协议QoS服务质量 (Quality of Service 0, 1 & 2)概念学习
什么是 QoS ? QoS (Quality of Service) 是发送者和接收者之间,对于消息传递的可靠程度的协商. QoS 的设计是 MQTT 协议里的重点.作为专为物联网场景设计的协议,MQ ...
- UVA-1322 Minimizing Maximizer (DP+线段树优化)
题目大意:给一个长度为n的区间,m条线段序列,找出这个序列的一个最短子序列,使得区间完全被覆盖. 题目分析:这道题不难想,定义状态dp(i)表示用前 i 条线段覆盖区间1~第 i 线段的右端点需要的最 ...
- OC Copy基本使用(深拷贝和浅拷贝)
首先,什么是copy? Copy的字面意思是“复制”.“拷贝”,是一个产生副本的过程. 常见的复制有:文件复制,作用是利用一个源文件产生一个副本文件. 特点:1.修改源文件的内容,不会影响副本文件: ...