程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1037 DP

POJ 1037 DP

編輯:C++入門知識

 
#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;  
}  

#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;
}





 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved