UVA - 10618(条件复杂的简单dp)

这个dp 没什么可说的,状态很容易想,

只是有两个地方容易出错,就是从当前位置进行转移,合法性的判断(特别注意 当右脚在左面,这这时候左脚是可以tap的)。

第二个,就是计算得分。千万注意啊。

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
const int maxn = 100;
int f(int pre,int now,int from,int to){
  if(!pre||now!=pre) return 1;
  if(abs(from - to) == 1 || abs(from - to) == 3) return 5;
  if(abs(from - to) == 2) { return 7;}
  if(abs(from - to) == 0) return 3;
}
int ok(int f,int l,int r,int to){
  if(f == 0){
      if(l == to) return 1;
      if(r == 3 || r == to) return 0;
      return 1;
  }
  else{
       if( r == to) return 1;
      if(l == 1 || l == to) return 0;
      return 1;
  }
}
int d[maxn][4][4][3],n;
struct node{
  int p,l,r,pre;
  node(int x=0,int y=0,int z=0,int w=0):
      p(x),l(y),r(z),pre(w){}
}pat[maxn][4][4][3];
char str[maxn];
const char* src="URDL";
int id(char c){
  if(c == '.') return -1;
  rep(i,4) if(src[i]==c) return i;
}
int cnt = 0;
void print_ans(int p,int l,int r,int pre){
  if(p == n) return;
  node& te = pat[p][l][r][pre];
  if(te.pre == 0) printf(".");
  else if(te.pre==1) printf("L");
  else printf("R");
  //if(cnt++ > n) return ;
  print_ans(te.p,te.l,te.r,te.pre);
}
int main()
{
   while(scanf("%s",str)!=EOF&&str[0]!='#'){
      n = strlen(str);
      for(int p=n;p>=0;p--)
        rep(l,4) rep(r,4) rep(pre,3){
         if(p == n){
            d[p][l][r][pre] = 0;
            continue;
         }
         if(l==r ||(r==3&&l==1)) continue;
         int& ans = d[p][l][r][pre];
         node& path = pat[p][l][r][pre];
         int to = id(str[p]);
         if(to == -1){
            ans = d[p+1][l][r][0];
            path = node(p+1,l,r,0);
            rep(i,4) if(ok(0,l,r,i)){
              if(d[p+1][i][r][1]+f(pre,1,l,i)<ans){
                 ans = d[p+1][i][r][1]+f(pre,1,l,i);
                 path = node(p+1,i,r,1);
              }
            }
            rep(i,4) if(ok(1,l,r,i)){
               if(d[p+1][l][i][2]+f(pre,2,r,i)<ans){
                 ans = d[p+1][l][i][2]+f(pre,2,r,i);
                 path = node(p+1,l,i,2);
               }
            }
         }
         else{
            ans = -1;
            if(ok(0,l,r,to)){
                ans = d[p+1][to][r][1]+f(pre,1,l,to);
                path = node(p+1,to,r,1);
            }
            if(ok(1,l,r,to)&&(ans==-1 ||ans>d[p+1][l][to][2]+f(pre,2,r,to))){
                ans = d[p+1][l][to][2]+f(pre,2,r,to);
                path = node(p+1,l,to,2);
            }
         }
      }
      print_ans(0,3,1,0);
      printf("\n");
   }
   return 0;
}


你可能感兴趣的:(Algorithm,C++,uva)