zoukankan      html  css  js  c++  java
  • 图论dp [ZJOI2006]物流运输

    区间dp+最短路。

    这一道题一开始没有思路,但观察了一下数据范围,果断大力dp。我们先用N^3logN 的复杂度预处理出 所有区间的最短路(就是区间内不改变路径的最短路),然后区间dp,dp转移方程为:f[i]=max(f[i],f[j]+k+(i-j+1)*cost[j,i]) (1<=j<=i) .。

    code:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<vector>
    #define int long long
    using namespace std;
    typedef pair<int,int>p; 
    const int maxn=2006;
    struct hzw
    {
    	int to,next,v;
    }e[maxn];
    int head[maxn],cur,dis[maxn],n,m,k,cnt,q,dp[maxn],cost[maxn][maxn];
    bool pan[maxn];
    vector<int>lmt[26];
    inline void add(int a,int b,int c)
    {
    	e[cur].to=b;
    	e[cur].next=head[a];
    	e[cur].v=c;
    	head[a]=cur++;
    }
    inline void dij()
    {
        priority_queue<p,vector<p>,greater<p> >q;
        memset(dis,0x3f,sizeof(dis));
        dis[1]=0;
        q.push(p(0,1));
        while (!q.empty())
        {
            p now=q.top();
            q.pop();
            int s=now.second;
            if (dis[s]< now.first) continue;
            for (int i=head[s];i!=-1;i=e[i].next)
            {
                if (dis[e[i].to]>dis[s]+e[i].v&&!pan[e[i].to])
                {
                    dis[e[i].to]=dis[s]+e[i].v;
                    q.push(p(dis[e[i].to],e[i].to));
                }
            }
        }
    }
    signed main()
    {
    	memset(head,-1,sizeof(head));
    	cin>>n>>m>>k>>cnt;
    	for (int i=1,a,b,c;i<=cnt;++i)
    	{
    		scanf("%lld%lld%lld",&a,&b,&c);
    		add(a,b,c);
    		add(b,a,c);
    	}
    	cin>>q;
    	for (int i=1,a,b,c;i<=q;++i)
    	{
    		scanf("%lld%lld%lld",&a,&b,&c);
    		for (int j=b;j<=c;++j)
    		{	
    			lmt[j].push_back(a);
    		}	
    	}
    	for (int i=1;i<=m;++i)
    	{
    		for (int j=i;j<=m;++j)
    		{
    			memset(pan,0,sizeof(pan));
    			for (int k=i;k<=j;++k)
    			{
    				for (int l=0;l<lmt[k].size();++l)
    				{
    					pan[lmt[k][l]]=1;
    				}
    			}
    			dij();
    			cost[i][j]=dis[n];
    //			cout<<"check: "<<i<<" "<<j<<" "<<cost[i][j]<<endl;
    		}
    	}
    	for (int i=1;i<=n;++i) dp[i]=1e17;
    	dp[1]=cost[1][1];
    	dp[0]=-k;
    	for (int i=2;i<=n;++i)
    	{
    		memset(pan,0,sizeof(pan));
    		for (int j=i;j>=1;--j)
    		{
    			if (cost[j][i]<0x3f3f3f3f-1)dp[i]=min(dp[i],dp[j-1]+k+cost[j][i]*(i-j+1));
    		}
    	}
    	cout<<dp[n];
    	return 0;
    }
    
    

    收获:

    1、变量不要打反。
    2、注意看数据范围,要勇敢一点。
    3、区间dp一般是f[i]=max(f[i],f[j]+g[j,i]);

  • 相关阅读:
    Scala中使用fastJson 解析json字符串
    SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量
    Spark 将DataFrame所有的列类型改为double
    Idea里面远程提交spark任务到yarn集群
    Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作
    scala之map,List,:: , +:, :+, :::, +++操作
    kafka auto.offset.reset参数解析
    spark-submit提交spark任务的具体参数配置说明
    docker plugin test
    docker ui
  • 原文地址:https://www.cnblogs.com/bullshit/p/9684513.html
Copyright © 2011-2022 走看看