zoukankan      html  css  js  c++  java
  • POJ 1037 DP

    题目链接: http://poj.org/problem?id=1037

    分析: 很有分量的一道DP题!!!

             (参考于:http://blog.csdn.net/sj13051180/article/details/6669737 )

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <iomanip>
    using namespace std;
    
    long long up[25][25];
    long long down[25][25];
    long long ans[25];
    
    void getfirst(long long n,long long c,bool u){
        if(n==0) return ;
        long long sum=0,t;
        if(!u) { //前一步是up,当前步要down
            t=ans[n+1];
            while(sum+down[n][t]<c)
                sum+=down[n][t++];
        } else { //前一步是down,当前步要up
            t=1;
            while(sum+up[n][t]<c)
                sum+=up[n][t++];
        }
        ans[n]=t;  //定位
        getfirst(n-1,c-sum,!u);  //搜索下一位
        for(int i=1;i<n;++i)
            if(ans[i]>=t) ++ans[i];
    }
    
    void Init(){
        up[1][1]=down[1][1]=1;
        for(int i=2; i<=20; ++i)
            for(int j=1; j<=i; ++j) {
                up[i][j]=down[i][j]=0;
                for(int k=j; k<=i-1; ++k)
                    up[i][j]+=down[i-1][k];
                for(int k=1; k<=j-1; ++k)
                    down[i][j]+=up[i-1][k];
            }
    }
    int main(){
        Init();
        int T; scanf("%d",&T);
        while(T--){
            long long c,n;
            scanf("%lld%lld",&n,&c); 
            
            long long sum=0,t=1;
            while(sum+up[n][t]+down[n][t]<c){
                sum+=up[n][t]+down[n][t];
                ++t;
            }
            ans[n]=t;  //定位首位
            //搜索下一位
            if(sum+down[n][t]<c)                      //在up中
                getfirst(n-1,c-sum-down[n][t],false);
            else                                      //在down中 
                getfirst(n-1,c-sum,true);
            for(int i=1;i<n;++i)// 比如当n=5时, 第一个选了t=3, 还有1,2,4,5 后面会对应到1,2,3,4, 大于t的都相对-1, 最终要+1 
                if(ans[i]>=t) ++ans[i];
                
            printf("%lld",ans[n]);
            for(int i=n-1;i>=1;--i)
                printf(" %lld",ans[i]);
            puts("");
        }
        return 0;
    }
    
    
    
    




  • 相关阅读:
    xml文档格式学习笔记
    Visual Studio学习记录
    Java学习笔记
    C#项目学习记录
    Linux命令行与shell脚本编程大全 学习笔记
    NodeJS (npm) 学习笔记
    Angular学习笔记
    TypeScript学习笔记
    java 项目相关 学习记录
    docker学习记录
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3209129.html
Copyright © 2011-2022 走看看