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-26 19:47
中南大学 Java
点赞 评论 收藏
分享
06-23 17:45
门头沟学院 Java
里面的项目啥的真的有用吗?&nbsp;这些人是割韭菜吗?
HellowordX:很简单,如果你有自己稳定的学习路线和获取知识的方式就没必要,如果你啥都不懂的小白或者里边有你感兴趣的知识,我觉得挺值,我也经常为知识付费,因为时间精力有限,很多东西我不可能自己重复造轮子
点赞 评论 收藏
分享
Southyeung:我说一下我的看法(有冒犯实属抱歉):(1)简历不太美观,给我一种看都不想看的感觉,感觉字体还是排版问题;(2)numpy就一个基础包,机器学习算法是什么鬼?我感觉你把svm那些写上去都要好一点。(2)课程不要写,没人看,换成获奖经历;(3)项目太少了,至少2-3个,是在不行把网上学习的也写上去。
点赞 评论 收藏
分享
湫湫湫不会java:先投着吧,大概率找不到实习,没实习的时候再加个项目,然后把个人评价和荣誉奖项删了,赶紧成为八股战神吧,没实习没学历,秋招机会估计不多,把握机会。或者说秋招时间去冲实习,春招冲offer,但是压力会比较大
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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