hdu 4996

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

#ifdef DEBUG
ifstream in;
ofstream out;
#endif

#ifdef DEBUG
#define CIN  in
#define COUT  out
#else
#define CIN  cin
#define COUT cout
#endif

#define CLR(vec) memset(vec, 0, sizeof(vec))
#define MAXN 20


typedef long long int ll;


ll dp[MAXN][MAXN];
ll record[1<<MAXN];
ll curr  [1<<MAXN];

int cset(int val){
    int cnt = 0;
    for(int idx = 0; idx < MAXN; idx++) if(val &(1 << idx))
            cnt++;
    return cnt;   
}

void init_dp(void){
    int len, val;
    CLR(dp);
    CLR(record);
    CLR(curr);
    dp[1][1] = 1;
    curr[1] = 1;
    for(len = 1; len < 18; len++){
            for(int status = 0; status < ( 1 << len); status++)
                record[status] = curr[status];
            for(int status = 0; status < ( 1 << (len + 1)); status++)
                curr[status] = 0;
            for(int oldstatus = 0; oldstatus < (1 << len); oldstatus++) if(record[oldstatus]){
                    for(val = 0; val <= len; val++){
                        int tot = 0;
                        int tmp[20];
                        for(int idx = 0; idx < len; idx++) if(oldstatus & (1 << idx))
                                    tmp[tot++] = idx;
                        for(int idx = 0; idx < tot; idx++) if(tmp[idx] >= val)
                                    tmp[idx]++;
                        tmp[tot++] = val;
                        for(int idx = 0; idx < tot; idx++) if(tmp[idx] > val){
                                    tmp[idx] = val; 
                                    break;
                        }
                        int newstatus = 0;
                        for(int idx = 0; idx < tot; idx++)
                                    newstatus |= ( 1 << tmp[idx]);
                        curr[newstatus] += record[oldstatus];
                    }
            }
        for(int status = 0; status < ( 1 << (1 + len)); status++)    
            dp[1 + len][cset(status)] += curr[status];
    } 
}


int  main(void)
{
#ifdef DEBUG
      string buffer;
      CIN.open("in", ios::in);
      COUT.open("out", ios::out);
      while(getline(CIN, buffer))
            COUT << buffer << "\n";
      COUT << "Out Put" << "\n";
      CIN.close();
      CIN.open("in", ios::in);
#endif  
      init_dp();
      int cases, n, k;
      CIN >> cases;
      for(int currCase = 1; currCase <= cases; currCase++){
            CIN >> n >> k;
            COUT  << dp[n][k] << endl;

      }
    return 0;
}


转载于:https://my.oschina.net/u/572632/blog/344175

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值