Post Office
2016-04-21 18:53
337 查看
http://poj.org/problem?id=1160这道题还是很难的(for me)看了题解才弄懂解题思路:动态规划分解出最优子结构 设dp[i][j]为i个邮局控制前j个村庄 例如i=2 j=4的时候其下有 (1,1)(2,3) (1,2)(2,2),(1,3)(2,1)这3种情况,我们取其中最小的那个。不难得出状态转移方程 dp[i][j]=min(dp[i-1][k]+cost[k+1][j]) i-1<=k<=j-1代码如下详细注释#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#define maxn 1000000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657
const ull inf = 1LL << 61;
const double eps=1e-5;
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int cost[310][310];
int dp[32][310]; ///i个邮局控制j个村庄
int a[310];
///状态转移方程为dp[i][j]=min(dp[i-1][k]+cost[k+1][j]) i-1<=k<=j-1
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int v,p;///v 村庄 p 邮局
while(cin>>v>>p)
{
cle(dp);
for(int i=1;i<=v;i++)
scanf("%d",&a[i]);
///构造cost[i][j] cost[i][j]表示i到j放一个邮局的最短距离和
for(int i=1;i<=v;i++)
for(int j=i;j<=v;j++)
{
cost[i][j]=0;
int mid=(i+j)/2;
for(int k=i;k<=j;k++)
{
cost[i][j]+=abs(a[k]-a[mid]);
}
}
///初始化 dp[i][j]邮局为1的情况
for(int i=1;i<=v;i++)
dp[1][i]=cost[1][i];
int Min;
for(int i=2;i<=p;i++)///枚举邮局
for(int j=i;j<=v;j++)///枚举村庄 从j=i开始和从j=1开始都行
{ Min=maxn;
for(int k=i-1;k<=j-1;k++)
{
Min=min(dp[i-1][k]+cost[k+1][j],Min);
}
dp[i][j]=Min;
}
cout<<dp[p][v]<<endl;
}
return 0;
}
![](http://img0.ph.126.net/zjfGkNFMNnEDdbCoevKDCg==/6598083516379276419.jpg)
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#define maxn 1000000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657
const ull inf = 1LL << 61;
const double eps=1e-5;
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int cost[310][310];
int dp[32][310]; ///i个邮局控制j个村庄
int a[310];
///状态转移方程为dp[i][j]=min(dp[i-1][k]+cost[k+1][j]) i-1<=k<=j-1
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int v,p;///v 村庄 p 邮局
while(cin>>v>>p)
{
cle(dp);
for(int i=1;i<=v;i++)
scanf("%d",&a[i]);
///构造cost[i][j] cost[i][j]表示i到j放一个邮局的最短距离和
for(int i=1;i<=v;i++)
for(int j=i;j<=v;j++)
{
cost[i][j]=0;
int mid=(i+j)/2;
for(int k=i;k<=j;k++)
{
cost[i][j]+=abs(a[k]-a[mid]);
}
}
///初始化 dp[i][j]邮局为1的情况
for(int i=1;i<=v;i++)
dp[1][i]=cost[1][i];
int Min;
for(int i=2;i<=p;i++)///枚举邮局
for(int j=i;j<=v;j++)///枚举村庄 从j=i开始和从j=1开始都行
{ Min=maxn;
for(int k=i-1;k<=j-1;k++)
{
Min=min(dp[i-1][k]+cost[k+1][j],Min);
}
dp[i][j]=Min;
}
cout<<dp[p][v]<<endl;
}
return 0;
}
![](http://img0.ph.126.net/zjfGkNFMNnEDdbCoevKDCg==/6598083516379276419.jpg)
相关文章推荐
- FatMouse\' Trade -HUD1009
- Piggy-Bank 完全背包问题
- How many ways 记忆化搜索
- Humble Numbers 丑数
- 关于图的深度优先的递归和非递归算法
- 搬寝室
- Common Subsequence(LCS)
- 最少拦截系统
- HDU 2577 How to Type
- Modified GCD
- A. Winner
- 免费馅饼
- 数塔
- 命运
- HDU 2602 Bone Collector
- HDU 4706 Children\'s Day
- HDU 1551 Cable master
- HDU 4708 Rotation Lock Puzzle
- Difference Between Primes----素数筛选
- HDU 1669 & poj 3122 pie