UVA 10564 Paths through the Hourglass

Problem

题意不太好描述..

Look up Original Problem From here

Solution

很显然就是dp。上沙锥一种情况,下沙锥一种情况。只说上沙锥的:dp[i][j][k]表示 第 i 行 第 j 列 总和为 k 时的方案数,则 dp[i][j][k+a[i][j]]=dp[i-1][j-1][k]+dp[i-1][j][k]。同时在记录下最小的路径即可。记录路径最好用结构体重载小于号,会比较方便。

My code

//Hello. I'm Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define pb(a) push_back(a)
#define clr(a) memset(a,0,sizeof(a))
#define clr_minus1(a) memset(a,-1,sizeof(a))
#define clr_INT(a) memset(a,INT,sizeof(a))
#define clr_true(a) memset(a,true,sizeof(a))
#define clr_false(a) memset(a,false,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
//const double pi=acos(-1.0);
//const double eps=1e-9;
#define MAXN 100100
#define N 40
#define M
int n,s;
struct Dpsta{
    ll x;
    int sp;
    string s;
    friend bool operator<(const Dpsta a,const Dpsta b){
        if(a.x==0&&b.x!=0) return false;
        else if(a.x!=0&&b.x==0) return true;
        if(a.sp<b.sp) return true;
        else if(a.sp>b.sp) return false;
        rep(i,0,slen(a.s)){
            if(a.s[i]<b.s[i]) return true;
            else if(a.s[i]>b.s[i]) return false;
        }
        return false;
    }
}dp[N][N][501],last;//dp[i][j]
int a[N][N];
int main(){
    while(~scanf("%d%d",&n,&s)&&(n+s)){
        int maxi=(2*n-1)*9;
        repin(i,1,n){
            repin(j,1,n-i+1){
                scanf("%d",&a[i][j]);
                if(s>maxi) continue;
                repin(k,0,s){
                    dp[i][j][k].x=0;
                }
            }
        }
        repin(i,n+1,2*n-1){
            repin(j,1,i-n+1){
                scanf("%d",&a[i][j]);
                if(s>maxi) continue;
                repin(k,0,s){
                    dp[i][j][k].x=0;
                }
            }
        }
        if(s>maxi){
            printf("%d\n\n",0);
            continue;
        }
        repin(j,1,n){
            int t=a[1][j];
            dp[1][j][t].x=1;
            dp[1][j][t].sp=j-1;
            dp[1][j][t].s.clear();
        }
        repin(i,2,n){
            repin(j,1,n-i+1){
                repin(k,0,s-a[i][j]){
                    int t=k+a[i][j];
                    dp[i][j][t].x+=dp[i-1][j][k].x;
                    dp[i][j][t].x+=dp[i-1][j+1][k].x;
                    if(dp[i][j][t].x==0) continue;
                    if(dp[i-1][j][k]<dp[i-1][j+1][k]){
                        dp[i][j][t].sp=dp[i-1][j][k].sp;
                        dp[i][j][t].s=dp[i-1][j][k].s+"R";
                    }
                    else{
                        dp[i][j][t].sp=dp[i-1][j+1][k].sp;
                        dp[i][j][t].s=dp[i-1][j+1][k].s+"L";
                    }
                }
            }
        }
        repin(i,n+1,2*n-1){
            repin(j,1,i-n+1){
                repin(k,0,s-a[i][j]){
                    int t=k+a[i][j];
                    if(j==1){
                        dp[i][j][t].x+=dp[i-1][j][k].x;
                        if(dp[i][j][t].x==0) continue;
                        dp[i][j][t].sp=dp[i-1][j][k].sp;
                        dp[i][j][t].s=dp[i-1][j][k].s+"L";
                    }
                    else if(j==i-n+1){
                        dp[i][j][t].x+=dp[i-1][j-1][k].x;
                        if(dp[i][j][t].x==0) continue;
                        dp[i][j][t].sp=dp[i-1][j-1][k].sp;
                        dp[i][j][t].s=dp[i-1][j-1][k].s+"R";
                    }
                    else{
                        dp[i][j][t].x+=dp[i-1][j-1][k].x;
                        dp[i][j][t].x+=dp[i-1][j][k].x;
                        if(dp[i][j][t].x==0) continue;
                        if(dp[i-1][j-1][k]<dp[i-1][j][k]){
                            dp[i][j][t].sp=dp[i-1][j-1][k].sp;
                            dp[i][j][t].s=dp[i-1][j-1][k].s+"R";
                        }
                        else{
                            dp[i][j][t].sp=dp[i-1][j][k].sp;
                            dp[i][j][t].s=dp[i-1][j][k].s+"L";
                        }
                    }
                }
            }
        }
        ll ansx=0;
        last.x=0;
        repin(j,1,n){
            ansx+=dp[2*n-1][j][s].x;
            if(dp[2*n-1][j][s].x!=0&&dp[2*n-1][j][s]<last){
                last.s=dp[2*n-1][j][s].s;
                last.sp=dp[2*n-1][j][s].sp;
                last.x=1;
            }
        }
        printf("%lld\n",ansx);
        if(ansx==0){
            printf("\n");
            continue;
        }
        printf("%d ",last.sp);
        cout<<last.s<<endl;
    }
    return 0;
}

你可能感兴趣的:(dp)