题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4996

题意:求1到n的全排列中,有多少个排列的最长上升子列长度为K?

思路:对于当前的最长上升子列,我们记录最后一个值得最小值即可。因此我们用2^n的状态表示当前最长上升子列中使用了哪些数字,且字典序最小。前n-1个数字之后,我们枚举最后一个位置的数字为[1,n]中每个数字,设为k,那么我们只要将前面[1,n-1]组成的数列中所有大于等于k的数字加一即可。

int n,k;

i64 f[22][22];
i64 dp[1<<22],tmp[1<<22];

int cal(int x)
{
    int ans=0;
    int i;
    for(i=0;i<20;i++) if(x&(1<<i)) ans++;
    return ans;
}

void init()
{
    dp[1]=1;
    f[1][1]=1;
    int i,j;
    for(i=1;i<18;i++)
    {

        for(j=0;j<(1<<i);j++) tmp[j]=dp[j];
        for(j=0;j<(1<<(i+1));j++) dp[j]=0;
        for(j=0;j<(1<<i);j++) if(tmp[j])
        {
            int k;
            for(k=0;k<=i;k++)
            {
                int tot=0;
                int c[20];
                int t;
                for(t=0;t<i;t++) if(j&(1<<t)) c[tot++]=t;
                for(t=0;t<tot;t++) if(c[t]>=k) c[t]++;
                c[tot++]=k;

                for(t=0;t<tot;t++) if(c[t]>k)
                {
                    c[t]=k;
                    break;
                }

                int st=0;
                for(t=0;t<tot;t++) st|=1<<c[t];
                dp[st]+=tmp[j];
            }
        }
        for(j=0;j<(1<<(i+1));j++) f[i+1][cal(j)]+=dp[j];
    }
}

int main()
{
    init();
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        printf("%I64d\n",f[n][k]);
    }
}

HDU 4996 Revenge of LIS(DP)的更多相关文章

  1. HDU 5078 Revenge of LIS II(dp LIS)

    Problem Description In computer science, the longest increasing subsequence problem is to find a sub ...

  2. hdu 5087 Revenge of LIS II (DP)

    题意: N个数,求第二长上升子序列的长度. 数据范围: 1. 1 <= T <= 1002. 2 <= N <= 10003. 1 <= Ai <= 1 000 0 ...

  3. hdu 5087 Revenge of LIS II

    http://acm.hdu.edu.cn/showproblem.php?pid=5087 题意求第二长的上升序列. 在求最长上升序列的同时加上一个数组,来记录以i为结尾的有多少条序列.如果n+1为 ...

  4. hdu 5087 Revenge of LIS II ( LIS ,第二长子序列)

    链接:hdu 5087 题意:求第二大的最长升序子序列 分析:这里的第二大指的是,全部的递增子序列的长度(包含相等的), 从大到小排序后.排在第二的长度 cid=546" style=&qu ...

  5. HDU 3341 Lost's revenge AC自动机+dp

    Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

  6. HDU 4352 XHXJ's LIS 数位dp lis

    目录 题目链接 题解 代码 题目链接 HDU 4352 XHXJ's LIS 题解 对于lis求的过程 对一个数列,都可以用nlogn的方法来的到它的一个可行lis 对这个logn的方法求解lis时用 ...

  7. HDOJ 5087 Revenge of LIS II DP

    DP的时候记录下能否够从两个位置转移过来. ... Revenge of LIS II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: ...

  8. HDU 4352 XHXJ's LIS HDU(数位DP)

    HDU 4352 XHXJ's LIS HDU 题目大意 给你L到R区间,和一个数字K,然后让你求L到R区间之内满足最长上升子序列长度为K的数字有多少个 solution 简洁明了的题意总是让人无从下 ...

  9. HDU5087——Revenge of LIS II(BestCoder Round #16)

    Revenge of LIS II Problem DescriptionIn computer science, the longest increasing subsequence problem ...

随机推荐

  1. Mysql自定义函数总结

    存储函数 创建存储函数,需要使用CREATE FUNCTION语句,基本语法如下: CREATE FUNCTION func_name([func_parameter]) RETURNS TYPE [ ...

  2. 夺命雷公狗---node.js---13之Buffer的转换

    其实Buffer也是一种数据结构的东西,但实际中用得并不多,我们只需要知道常用的转换方法即可: /** * Created by leigood on 2016/8/30. */ var str = ...

  3. 转:VS2008 vs2010中JQUERY智能提醒

    第一步: 安装VS 2008 SP1 VS 2008 SP1 在Visual Studio中加了更丰富的JavaScript intellisense支持,对很大部分的JavaScript库加了代码完 ...

  4. 不小心rm删除文件怎么办

    不小心rm删除文件怎么办 rm 命令的副作用越来越显现.而且rm掉之后的东西想找回来很困难.有2个原则: 1 永远不要在root下操作,尤其是rm命令 2 写一个别名,代替rm 我就是在~/.bash ...

  5. 通过Oracle数据库访问控制功能的方法(Database access control)

    修改sqlnet.ora文件中的IP列表后都需要重启监听才能生效.(原文是: Any changes to the values requires the TNS listener to be sto ...

  6. PHP stat() 函数 返回关于文件的信息。

    定义和用法 stat() 函数返回关于文件的信息. 语法 fstat(file) 参数 描述 file 必需.规定要检查的文件. 说明 获取由 file 指定的文件的统计信息.如果 file 是符号连 ...

  7. Asp.net mvc5 解析route源码实现自己的route系统

    url route 路由系统的责任是找到匹配的路由,创建路由数据,并将请求分配给一个处理程序. 选择动作是 MVC 的处理程序的实现细节.它使用路由数据和从传入请求其他信息来选择要执行的操作 实例 源 ...

  8. bianwu | 数据行 | 填写意见

    protected void gv1_RowDataBound(object sender, GridViewRowEventArgs e) { //首先判断是否是数据行 if (e.Row.RowT ...

  9. [ios]纯代码实现UITableViewCell的自定义扩展

    (转)参考:http://blog.sina.com.cn/s/blog_65cbfb2b0101cd60.html 第一种, 简单的增加UITableViewCell一些小功能 例如在cell上面添 ...

  10. 简单排序算法设计(Java)

    总共有八种排序算法,还是慢慢看吧 1.简单排序算法 简单排序算法就是设置标兵,逐个比较数,然后查找插入位置,插入 public static void p(int[] a){ for(int i=0; ...