codeforces 152E Garden(状态压缩dp)
2015-05-25 19:21
253 查看
题目链接
E. Garden
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Vasya has a very beautiful country garden that can be represented as an n × m rectangular
field divided into n·m squares. One beautiful
day Vasya remembered that he needs to pave roads between k important squares that
contain buildings. To pave a road, he can cover some squares of his garden with concrete.
For each garden square we know number aij that
represents the number of flowers that grow in the square with coordinates (i, j).
When a square is covered with concrete, all flowers that grow in the square die.
Vasya wants to cover some squares with concrete so that the following conditions were fulfilled:
all k important squares should necessarily be covered with concrete
from each important square there should be a way to any other important square. The way should go be paved with concrete-covered squares considering that neighboring squares are squares that have a common side
the total number of dead plants should be minimum
As Vasya has a rather large garden, he asks you to help him.
Input
The first input line contains three integers n, m and k (1 ≤ n, m ≤ 100, n·m ≤ 200, 1 ≤ k ≤ min(n·m, 7))
— the garden's sizes and the number of the important squares. Each of the next n lines
contains m numbers aij (1 ≤ aij ≤ 1000)
— the numbers of flowers in the squares. Next k lines contain coordinates of important
squares written as "x y"
(without quotes) (1 ≤ x ≤ n, 1 ≤ y ≤ m).
The numbers written on one line are separated by spaces. It is guaranteed that all k important
squares have different coordinates.
Output
In the first line print the single integer — the minimum number of plants that die during the road construction. Then print n lines
each containing m characters — the garden's plan. In this plan use character "X"
(uppercase Latin letter X) to represent a concrete-covered square and use character "." (dot) for a square that isn't covered with concrete. If there are multiple solutions, print any of them.
Sample test(s)
input
output
input
output
非常好的一道状态压缩动态规划的题目!!
题意:n*m的网格图,每个格子都有一定价值的花aij。有k个重要的格子,现在可以用水泥来填一个格子,填完以后损失这个格子的花的价值。相邻两个被水泥填的格子可以相互连通。问让k个重要的格子连通,最少要损失的花的价值?并输出方案。
题解:由于k<=7,所以考虑状态压缩动态规划来求解。
用dp[mask][v]表示mask状态(k位二进制状态,第i位为1表示选,否则不选)的重要的点相互连通,第v个点必选的最小花费。
转移有两种:
第一:点v可以把当前连通块分成两个不同的连通块,则:
dp[mask][v] = min ( dp[ submask ][ v ] + dp[ mask^submask ][ v ] - cost( v ) )
第二:如果点v不能把当前连通块分成两个块,则:
dp[mask][v]=min( dp[ mask ][ u ] + dis( u,v ) - cost( u ) ) ;
dis(u,v)表示连接u,v的最小花费,cost( u ) 表示点u的花费
代码如下:
E. Garden
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Vasya has a very beautiful country garden that can be represented as an n × m rectangular
field divided into n·m squares. One beautiful
day Vasya remembered that he needs to pave roads between k important squares that
contain buildings. To pave a road, he can cover some squares of his garden with concrete.
For each garden square we know number aij that
represents the number of flowers that grow in the square with coordinates (i, j).
When a square is covered with concrete, all flowers that grow in the square die.
Vasya wants to cover some squares with concrete so that the following conditions were fulfilled:
all k important squares should necessarily be covered with concrete
from each important square there should be a way to any other important square. The way should go be paved with concrete-covered squares considering that neighboring squares are squares that have a common side
the total number of dead plants should be minimum
As Vasya has a rather large garden, he asks you to help him.
Input
The first input line contains three integers n, m and k (1 ≤ n, m ≤ 100, n·m ≤ 200, 1 ≤ k ≤ min(n·m, 7))
— the garden's sizes and the number of the important squares. Each of the next n lines
contains m numbers aij (1 ≤ aij ≤ 1000)
— the numbers of flowers in the squares. Next k lines contain coordinates of important
squares written as "x y"
(without quotes) (1 ≤ x ≤ n, 1 ≤ y ≤ m).
The numbers written on one line are separated by spaces. It is guaranteed that all k important
squares have different coordinates.
Output
In the first line print the single integer — the minimum number of plants that die during the road construction. Then print n lines
each containing m characters — the garden's plan. In this plan use character "X"
(uppercase Latin letter X) to represent a concrete-covered square and use character "." (dot) for a square that isn't covered with concrete. If there are multiple solutions, print any of them.
Sample test(s)
input
3 3 2 1 2 3 1 2 3 1 2 3 1 2 3 3
output
9 .X. .X. .XX
input
4 5 4 1 4 5 1 2 2 2 2 2 7 2 4 1 4 5 3 2 1 7 1 1 1 1 5 4 1 4 4
output
26 X..XX XXXX. X.X.. X.XX.
非常好的一道状态压缩动态规划的题目!!
题意:n*m的网格图,每个格子都有一定价值的花aij。有k个重要的格子,现在可以用水泥来填一个格子,填完以后损失这个格子的花的价值。相邻两个被水泥填的格子可以相互连通。问让k个重要的格子连通,最少要损失的花的价值?并输出方案。
题解:由于k<=7,所以考虑状态压缩动态规划来求解。
用dp[mask][v]表示mask状态(k位二进制状态,第i位为1表示选,否则不选)的重要的点相互连通,第v个点必选的最小花费。
转移有两种:
第一:点v可以把当前连通块分成两个不同的连通块,则:
dp[mask][v] = min ( dp[ submask ][ v ] + dp[ mask^submask ][ v ] - cost( v ) )
第二:如果点v不能把当前连通块分成两个块,则:
dp[mask][v]=min( dp[ mask ][ u ] + dis( u,v ) - cost( u ) ) ;
dis(u,v)表示连接u,v的最小花费,cost( u ) 表示点u的花费
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<math.h> #include<queue> #include<stack> #include<set> #include<map> #include<vector> #include<string.h> #include<string> #include<stdlib.h> typedef __int64 LL; typedef unsigned __int64 LLU; const int nn=110; const int inf=0x3fffffff; const LL inf64=(LL)inf*inf; const double eps=1e-8; using namespace std; int n,m,k; int a[nn][nn]; int dp[(1<<7)+10][nn][nn]; bool use[nn][nn]; int dir[4][2]={1,0,-1,0,0,1,0,-1}; struct node { int mask,x,y; node(){} node(int mmask,int xx,int yy) { mask=mmask,x=xx,y=yy; } }; node pre[(1<<7)+10][nn][nn]; queue<node>que; bool inque[(1<<7)+10][nn][nn]; void solve(int mask,int x,int y) { if(pre[mask][x][y].mask==-1) return ; if(pre[mask][x][y].mask==0) { solve(pre[mask][x][y].x,x,y); solve(pre[mask][x][y].y,x,y); } else { use[x][y]=true; solve(mask,pre[mask][x][y].x,pre[mask][x][y].y); } } int main() { int i,j,x,y,e; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&a[i][j]); } } memset(use,false,sizeof(use)); memset(inque,false,sizeof(inque)); for(e=0;e<(1<<k);e++) { for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { dp[e][i][j]=inf; pre[e][i][j]=node(-1,-1,-1); } } } for(i=0;i<k;i++) { scanf("%d%d",&x,&y); dp[(1<<i)][x][y]=a[x][y]; use[x][y]=true; que.push(node(1<<i,x,y)); inque[(1<<i)][x][y]=true; } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(!use[i][j]) { dp[0][i][j]=a[i][j]; que.push(node(0,i,j)); inque[0][i][j]=true; } } } node sta; while(que.size()) { sta=que.front(); que.pop(); inque[sta.mask][sta.x][sta.y]=false; for(e=1;e<(1<<k);e++) { if((e&sta.mask)==0) { if(dp[e^sta.mask][sta.x][sta.y]>dp[sta.mask][sta.x][sta.y]+dp[e][sta.x][sta.y]-a[sta.x][sta.y]) { pre[e^sta.mask][sta.x][sta.y]=node(0,sta.mask,e); dp[e^sta.mask][sta.x][sta.y]=dp[sta.mask][sta.x][sta.y]+dp[e][sta.x][sta.y]-a[sta.x][sta.y]; if(!inque[e^sta.mask][sta.x][sta.y]) { inque[e^sta.mask][sta.x][sta.y]=true; que.push(node(e^sta.mask,sta.x,sta.y)); } } } } for(i=0;i<4;i++) { int dx=sta.x+dir[i][0]; int dy=sta.y+dir[i][1]; if(dx>=1&&dx<=n&&dy>=1&&dy<=m) { if(dp[sta.mask][dx][dy]>dp[sta.mask][sta.x][sta.y]+a[dx][dy]) { pre[sta.mask][dx][dy]=node(1,sta.x,sta.y); dp[sta.mask][dx][dy]=dp[sta.mask][sta.x][sta.y]+a[dx][dy]; que.push(node(sta.mask,dx,dy)); inque[sta.mask][dx][dy]=true; } } } } int ans=inf; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(dp[(1<<k)-1][i][j]<ans) { ans=dp[(1<<k)-1][i][j]; sta=node((1<<k)-1,i,j); } } } printf("%d\n",ans); solve(sta.mask,sta.x,sta.y); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { printf("%c",use[i][j]?'X':'.'); } puts(""); } } return 0; }
相关文章推荐
- CodeForces 11D - A Simple Task 状态压缩DP
- CodeForces 8C - Looking for Order 状态压缩DP..DP降低复杂度
- codeforces 16E Fish(状态压缩概率DP)
- codeforces 285 D Permutation Sum (状态压缩DP)
- 状态压缩DP codeforces 244 Problem C. The Brand New Function 和 codeforces 165 E. Compatible Numbers
- Codeforces 4538 (状态压缩dp)Little Pony and Harmony Chest
- CodeForces - 165E(状态压缩dp)
- Codeforces 11D A Simple Task (状态压缩DP)
- codeforces 543C C. Remembering Strings(状态压缩dp)
- (状态压缩dp)Codeforces 543 C-Remembering Strings
- Codeforces 417D Cunning Gena(状态压缩dp)
- codeforces 580D Kefa and Dishes【状态压缩+dp】
- Codeforces,Kefa and Dishes,状态压缩DP
- codeforces 321# D. Kefa and Dishes (状态压缩DP)
- CodeForces 21D - Traveling Graph 欧拉回路的性质+状态压缩DP
- codeforces 424E Colored Jenga (状态压缩,概率dp用hash记忆优化搜索)
- Codeforces 417D Cunning Gena(状态压缩dp)
- Codeforces 8C Looking for Order(状态压缩DP)
- codeforces 453B Little Pony and Harmony Chest (离散化+dp状态压缩)
- CodeForces 903F Clear The Matrix (状态压缩dp)