加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

hdu5568 sequence2(dp+大数)

发布时间:2020-12-14 02:12:09 所属栏目:大数据 来源:网络整理
导读:题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5568 题目大意: 给一段长度为n的序列,现在在其中取k个,问这k个是递增的取法有多少种。 范围:n=100。 思路: 可以用dp来解决,跟前面做过的一题一样。 设f[i][j],代表在前i个里面选了长度为j并且

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5568

题目大意:

给一段长度为n的序列,现在在其中取k个,问这k个是递增的取法有多少种。

范围:n<=100。

思路:

可以用dp来解决,跟前面做过的一题一样。

设f[i][j],代表在前i个里面选了长度为j并且以a[i]为结尾的取法,那么就有转移方程:f[i][j]=Σf[k][j-1](a[k]<a[i])。

时间复杂度O(n^3)。

但是考虑极端情况,100个里面取50个的时候,很显然已经溢出了,所以这里用大数处理。字符串模拟一下即可。

代码:

#include<stdio.h>
#include<string.h>
#define ll __int64
 char f[105][105][505];
 int max(int a,int b)
 {
     return a>b?a:b;
 }
 void add(int x,int y,int z)
 {
     if(z<y-1)return;
     char s[500];
     int q=0,i,j,t=0,l1,l2;
     l1=l2=0;
     for(i=0;i<500;i++)
        s[i]=0;
        for(i=499;i>=0;i--)
        {
            if(t==0&&f[x][y][i]==0)continue;
            else if(t==0&&f[x][y][i]){l1++;t=1;}
            else {l1++;}
        }
        t=0;
        for(i=499;i>=0;i--)
        {
            if(t==0&&f[z][y-1][i]==0)continue;
            else if(t==0&&f[z][y-1][i]){l2++;t=1;}
            else l2++;
        }
        t=0;
        q=0;
    for(i=0,j=0;i<l1&&j<l2;i++,j++)
    {
        s[q]=s[q]+f[x][y][i]+f[z][y-1][j];
        if(s[q]>=10){
            s[q]-=10;
            s[q+1]++;

        }
        q++;
    }
    while(i<l1){
        s[q]=s[q]+f[x][y][i];
        if(s[q]>=10){
            s[q]-=10;
            s[q+1]++;
        }
        i++;
        q++;
    }
    while(j<l2){
        s[q]=s[q]+f[z][y-1][j];
        if(s[q]>=10){
            s[q]-=10;
            s[q+1]++;
        }
        j++;
        q++;
    }
    int flag=0,xx=0;
    for(i=499;i>=0;i--)
    {
        if(flag==0&&s[i]==0)continue;
        else if(flag==0&&s[i]){
            flag=1;
            f[x][y][i]=s[i];
        }
        else f[x][y][i]=s[i];
    }

 }
int main()
{
      int  n,k,b[105];
    while(scanf("%d%d",&n,&k)!=EOF){
        memset(f,sizeof(f));
        for(i=1;i<=n;i++)
            scanf("%d",&b[i]);
         for(i=1;i<=n;i++)
            f[i][1][0]=1;
         for(i=1;i<=n;i++)
            {for(j=2;j<=k;j++)
         {
             if(i<j)continue;
             for(int l=1;l<i;l++)
                if(b[l]<b[i])add(i,l);
         }
    }

        char s[500],sum[500];
        for(i=0;i<500;i++)
            {s[i]=sum[i]=0;}
         for(i=1;i<=n;i++)
            {
                if(i<k)continue;
                int q=0,w=0;
               for(j=499;j>=0;j--)
               {
                   if(q==0&&f[i][k][j]==0)continue;
                   else if(q==0&&f[i][k][j]){
                    s[w++]=f[i][k][j];q=1;

                   }
                   else {s[w++]=f[i][k][j];}
               }
               for(j=0;j<w;j++)
               {
                   int x=s[w-1-j]+sum[j];
                   if(x>=10){
                    sum[j]=x-10;
                    sum[j+1]++;
                   }
                   else sum[j]=x;
               }
            }
            int ff=0;
        for(i=499;i>=0;i--)
        {
            if(ff==0&&sum[i]==0)continue;
            else if(ff==0&&sum[i]>0){
                printf("%d",sum[i]);
                ff=1;
            }
            else printf("%d",sum[i]);
        }
        if(ff==0)printf("0");
         printf("n");
    }
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读