zoukankan      html  css  js  c++  java
  • [codevs1243]网络提速

    题目大意:有n台电脑,m个加速器,每台电脑之间传输文件有一个时间,每个加速器可以使传输时间减半(两台电脑之间可以有多个加速器),求电脑1传输文件到电脑n的最短时间。

    解题思路:有些人先求出最短路径,再每次找当前最短路径的最长边用加速器(即贪心),然而这种方法有反例。例如:

    3 1

    0 3 7

    3 0 3

    7 3 0

    贪心的话求出来的是4.5(1-2-3,在1-2或2-3之间用加速器),然而最优解是3.5(1-3,在1-3之间用加速器)。

    正确的解法应该是:最短路径+DP……吧(反正就是有点像最短路径又有点像DP的东西)。

    直接上代码,在代码中有注释。

    C++ Code:

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cmath>
    using namespace std;
    const double inf=1e30;//inf表示这两台计算机不能直接传输文件(t)/还没有解(dp)。
    int n,m;
    double t[51][51][11],dp[51][11];
    //t[i][j][k]表示从第i台计算机到第j台用k台加速器的用时,dp[i][j]表示从第1台计算机到第i台用了j台加速器的最短用时。
    typedef pair<int,int> pr;//第一个int保存当前的计算机编号,第二个int表示当前用了几台加速器。
    queue<pr>q;
    void work(){
    	q.push((pr){1,0});
    	while(!q.empty()){
    		int num=q.front().first,jsq=q.front().second;
    		q.pop();
    		for(int i=1;i<=n;++i){
    			if(fabs(t[num][i][0]-inf)>0.000001){
    				for(int j=jsq;j<=m;++j){//枚举要使用的加速器台数 
    					if(dp[i][j]>dp[num][jsq]+t[num][i][j-jsq]){//DP?SPFA? 
    						dp[i][j]=dp[num][jsq]+t[num][i][j-jsq];
    						q.push((pr){i,j});
    					}
    				}
    			}
    		}
    	}
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)
    	for(int j=1;j<=n;++j){
    		scanf("%lf",&t[i][j][0]);
    		if(t[i][j][0]==0)t[i][j][0]=inf;else
    		for(int k=1;k<=m;++k)t[i][j][k]=t[i][j][k-1]/2;//预处理
    	}
    	memset(dp,0,sizeof dp);
    	for(int i=2;i<=n;++i)
    	for(int j=0;j<=m;++j)dp[i][j]=inf;
    	work();
    	printf("%.2f
    ",dp[n][m]);//因为用完m个加速器肯定比少用的优,所以答案是dp[n][m]。 
    	return 0;
    }
    
  • 相关阅读:
    Linux/UNIX编程:实现简单 tee 命令
    Java原子变量类需要注意的问题
    一种很有意思的数据结构:Bitmap
    Java实现简单井字棋
    分治算法学习
    使用栈实现表达式求值
    Web安全学习笔记——SQL注入
    【old】Python学习笔记
    函数1
    pycharm(Tip of Day)
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7245702.html
Copyright © 2011-2022 走看看