周赛第三次题目。基本的dp,比较简单。注意第一行右边的格子只能从中间走过去:dp[0][2] = d2 + d3;
  第二行左边格子只能从第一行中间格子走到:dp[1][0] = d1 + dp[0][1];
  第二行中间格子从第一行的中间,右边和第二行的左边格子走到:dp[1][1] = min2(dp[1][0],dp[0][1],dp[0][2]);
  其余情况看箭头确定状态转移。
View Code
// source code of submission 736533, Zhongshan University Online Judge System
#include <iostream>
#include
<cstring>
#include
<stdio.h>

using namespace std;
const int MAX = 100002;
long long dp[MAX][4];
int d1,d2,d3,n;

long long min1(long long x,long long y)
{
if(x < y) return x;
else return y;
}

long long min2(long long a,long long b,long long c)
{
long long _min = a;
if(_min > b) _min = b;
if(_min > c) _min = c;

return _min;
}

long long min3(long long a,long long b,long long c,long long d)
{
long long _min = a;
if(_min > b) _min = b;
if(_min > c) _min = c;
if(_min > d) _min = d;

return _min;
}

int main()
{
int i,ca = 0;

while(scanf("%d",&n) && n)
{
scanf(
"%d %d %d",&d1,&d2,&d3);
dp[
0][0] = 0; dp[0][1] = d2; dp[0][2] = d2 + d3;

for(i = 1;i < n;++i)
{
scanf(
"%d %d %d",&d1,&d2,&d3);

if(i == 1)
{
dp[i][
0] = d1 + dp[i-1][1];
dp[i][
1] = d2 + min2(dp[i][0],dp[i-1][1],dp[i-1][2]);
dp[i][
2] = d3 + min2(dp[i][1],dp[i-1][1],dp[i-1][2]);
}
else
{
dp[i][
0] = d1 + min1(dp[i-1][0],dp[i-1][1]);
dp[i][
1] = d2 + min3(dp[i][0],dp[i-1][0],dp[i-1][1],dp[i-1][2]);
dp[i][
2] = d3 + min2(dp[i][1],dp[i-1][1],dp[i-1][2]);
}
}

printf(
"%d. %d\n",++ca,dp[n-1][1]);
}

return 0;
}
posted on 2011-04-23 23:33  c++fans  阅读(310)  评论(0编辑  收藏  举报