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

    思路:

    这题要求最长下降子序列的长度和个数,我们可以增加 数组maxlen[size](记录当前第1个点到第i个点之间的最长下降序列长度) 和maxnum[size](记录1~i之间的最长下降序列个数 ) ,首先对于最长下降序列属于DP基础题,只要对每一个a[i]求出符合要求(a[i] < a[j])的max( maxlen[j] + 1)即可,主要难点在第二步求下降序列总数

    在序列中,如果maxlen[j]+1 == maxlen[i]则说明a[i]和a[j]在同一个下降数列中(显然必有a[i]< a[j]),那么我们只要将每一种符合要求的状态maxnum[j]转移到maxnum[i]中就可以了,有几个细节需要注意,题目要求序列是严格递减的,那么对于两个相同的数我们只能记录一个合法解,那么程序必须只记录两个相同数之间的状态,在这里用倒推可以简化编程,只要找到一个等于的就直接跳出循环,还要注意,如果从当前的a[i]一直找到相等的a[j]在这之间都没有可行状态的话,当maxnum[i]默认值为1要修改为0(避免错误计算),为0的当然无需处理。

    转自:http://blog.csdn.net/zhang360896270/article/details/6701589

    // by SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n,a[5005],f[5005],ans=0,ans2=0,cnt[5005];
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)f[i]=cnt[i]=1;
        for(int i=2;i<=n;i++)
            for(int j=i-1;j;j--)
                if(a[i]<a[j]){
                    if(f[i]<f[j]+1)
                        f[i]=f[j]+1,cnt[i]=cnt[j];
                    else if(f[i]==f[j]+1)
                        cnt[i]+=cnt[j];
                }
                else if(a[i]==a[j]){
                    if(f[i]==1)
                        cnt[i]=0;
                    break;
                }
        for(int i=1;i<=n;i++)
            if(ans<f[i])
                ans=f[i],ans2=cnt[i];
            else if(ans==f[i])
                ans2+=cnt[i];
        printf("%d %d",ans,ans2);
    }
  • 相关阅读:
    PHP :cookie用法
    php数组变化
    js引入
    python中wx模块的具体使用方法
    python随机模块random的22种函数(小结)
    python 数据库查询返回list或tuple实例
    Python使用Excel将数据写入多个sheet
    使用Python实现将多表分批次从数据库导出到Excel
    Python基础学习笔记之数据类型
    python Django 反向访问器的外键冲突解决
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532336.html
Copyright © 2011-2022 走看看