Fast Food(DP)



题意:
给你n个饭店在横坐标轴上的位置,要你在这些饭店旁边建立k个仓库,使得所有饭店到最近的仓库距离之和最短,要你输出这个值。
思路:
这个题可以认为是管道问题的扩展版本,也可以认为是矩阵链乘的变种。
定义dp[ i ] [ j ]:表示一共i个仓库在[1, j] 这些饭店的最短距离和
转移方程:dp[ i ][ j ] = min(dp[i - 1] [k - 1] + dis[ k ] [ j ]) i取值[1,k],j取值[i , j],k取值[i , j]。
这里用到了dis[ i ] [ j ]:表示从第i个饭店到第j个饭店最短路径和(中位数原理即可)
注意:
j不能取i + 1(j的话我觉得取i + 1应该没问题,前面i个都放仓库就是0不用再计算,但是可能会出现玄学错误,但是我们再for两次下三角等于0,然后取j = i + 1就可以了),k 不能取 i + 1(就是断开位置从i开始,至于为什么答案是显然的从i + 1开始会错过一些最优值,比如从i开始断开更优,这里开始没有考虑好。。。)
代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e3 + 10;
int a[maxn],dis[maxn][maxn],dp[maxn][maxn];
void solved(){
	int ca = 1;
	int n,k;
	while(cin>>n>>k &&  (n || k)){
		memset(a,0,sizeof(a));
		for(int i = 1; i <= n; i++){
			cin>>a[i];
		}
		memset(dis,0,sizeof(dis));
		for(int i = 1; i <= n; i++){ 
			for(int j = i + 1; j <= n; j++){
				for(int k = i; k <= j; k++){
					dis[i][j] += abs(a[(i + j) / 2] - a[k]);	
				} 
			}
		}
		memset(dp,0x3f,sizeof(dp));
		for(int i = 1; i <= n; i++)dp[1][i] = dis[1][i];
		for(int i = 2; i <= k; i++){//枚举仓库数量 
			for(int j = i; j <= n; j++){//枚举区间[i,j] 
				for(int k = i; k <= j; k++){//枚举断开位置k 
					dp[i][j] = min(dp[i - 1][k - 1] + dis[k][j],dp[i][j]);
				}
			}
		}
		cout<<"Chain "<<ca++<<endl;
		cout<<"Total distance sum = "<<dp[k][n]<<endl;
		cout<<endl;
	}
}
int main(){
	solved();
	return 0;
}

总结:
这几天写题老是有点心浮气躁的,一定要冷静啊!!!

全部评论

相关推荐

不愿透露姓名的神秘牛友
06-23 16:31
点赞 评论 收藏
分享
06-23 23:49
中南大学 Java
成绩一坨屎,英语6级没过,没读研,没考教资,没考计算机二级,没考公,没谈过恋爱,你们说我的这个大学生涯是不是混的有点失败啊?哎老中一生的容错还是太低了下辈子一定注意混好大学生涯不留遗憾
K1einMoretti:1.不保研 成绩没太大用 2.6级没过看用人企业要求了,基本上只要4级以上 3. 读不读研看自己选择,现在这环境螚先就业就先就业 4. 你不当老师考啥教资 5. 计算机二级没用(这证纯给国家上供) 6. 订婚***案了解一下?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务