C. Gas Pipeline

链接:http://codeforces.com/contest/1207/problem/C

题意:有一条路,除了首尾,中间可能会有一些十字路口,而你需要设置一些管道,当有十字路口时需要抬升,不同的方案造价不同,给与管道与柱子的花费,给出最小开销。

题解:用贪心也是可以的,不过我觉得dp更加富有美感。

下面给出dp代码:

#include
#include
#include
#include
#include 
#include
#include
#include 
#include
#include 
#define INF 0x3f3f3f3f
#define lowbit(a) ((a)&-(a))
#define speed std::ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
using namespace std;
typedef long long ll;
queue<int> q;
priority_queue<int> pq;  
const int maxn = 200005;
ll n,m,l,r;
ll ans=0;
ll dp[maxn][2];
int main()
{
 int T;
 cin>>T;
 while(T--)
 {
  string s;
  ll a,b;
     cin>>n>>a>>b;
        cin>>s;
        dp[0][0]=b;
  dp[0][1]=1e15;//前一个代表格子位置,后一个代表01状态(是否有十字路口)
  for(int i=0;i<n;i++)
  {
   if(s[i]=='0')
   {//这一项是0了,下一项0就可以下降(上升)处理,判断是下降(上升)花费少还是连着花费少
    dp[i+1][1]=min(dp[i][0]+a*2+2*b,dp[i][1]+a+b*2);//下一项是1时,前面是上升,后面是连着 
    dp[i+1][0]=min(dp[i][0]+a+b,dp[i][1]+a*2+b);//下一项是0时,前面是连着,后面是下降 
   }
   else{
    dp[i+1][1]=dp[i][1]+a+2*b,dp[i+1][0]=1e15;//+a+2*b是连着的开销 
   }//如果这一项是1,则下一0状态失去意义(因为需要两个连着的0才能下降处理),用无穷大处理,使其对后面判断不出现影响
  }
  printf("%I64d\n",dp[n][0]);//根据状态,n为终点,0为最后确定的状态(题意)
 }
 return 0;
}

你可能感兴趣的:(C. Gas Pipeline)