• 美丽数列


    链接:https://ac.nowcoder.com/acm/problem/21313
    来源:牛客网

    题目描述

    牛牛喜欢整数序列,他认为一个序列美丽的定义是
    1:每个数都在0到40之间
    2:每个数都小于等于之前的数的平均值
    具体地说:for each i, 1 <= i < N,  A[i] <= (A[0] + A[1] + ... + A[i-1]) / i.
    3:没有三个连续的递减的数

    现在给你一个序列,每个元素是-1到40,你可以将序列中的-1修改成任意的数,求你可以得到多少个美丽序列,答案对1e9+7取模

    输入描述:

    第一行输入一个整数n (1 ≤ n ≤ 40)

    第二行输入n个整数

    输出描述:

    输出一个整数

    感觉难的点: -1的讨论,dp,平均数 思路: 二维dp[i][j] 表示第i个数是j的可能性的种数;但是平均数没法记录: dp[i[[j][k]表示第i个数是j并且前i个数之和平均数为k的种数; 没想到的点: flag 还要再加一个维度;平均数用sum代替比较好; dp[i][j][L][sum] 代码细节: dp也要是long long。。
    #include<bits/stdc++.h>
    using namespace std;
    
    long long dp[45][45][3][1605];
    const int mod= 1e9+7;
    int  a[43];
    int main(){
        int n;
        cin >> n;
        
        for(int i = 1; i <= n; i++)
            cin >> a[i];
        memset(dp,0,sizeof(dp));
        //初始化
        if (a[1] == -1)
            for(int j = 0; j <= 40; j++)   dp[1][j][1][j] = 1;
        else    dp[1][a[1]][1][a[1]] = 1;
         
        for(int i = 2; i <= N; i++)
            if(a[i] == -1){// j 0-40
                for(int j = 0; j <=40; j++)//枚举当前可能的数 0~40
                    for(int k = 0; k <= 40; k++){//枚举当前前一个(i-1)可能的数 0~40
                        for(int sum = j*(i-1); sum<=1600-j; sum++)//枚举前(i-1)个满足条件的和sum;
                            if(j >= k){// 当前的数大于之前的数,有两种情况
                                dp[i][j][1][sum+j] += dp[i-1][k][1][sum] + dp[i-1][k][2][sum];
                                dp[i][j][1][sum+j] %= mod;
                            }else//当前的数小于之前的数,只有一种情况。
                            {
                                dp[i][j][2][sum+j] += dp[i-1][k][1][sum];
                                dp[i][j][2][sum+j] %= mod;
                            }                       
                    }
            }
            else
            {
                int j = a[i];// j只能取a[i]
                for(int k = 0; k <= 40; k++){
                        for(int sum = j*(i-1); sum<=1600-j; sum++)
                            if(j >= k){
                                dp[i][j][1][sum+j] += dp[i-1][k][1][sum] + dp[i-1][k][2][sum];
                                dp[i][j][1][sum+j] %= mod;
                            }else
                            {
                                dp[i][j][2][sum+j] += dp[i-1][k][1][sum];
                                dp[i][j][2][sum+j] %= mod;
                            }
                            
                    }
            }
         
       long long ans = 0;
        for(int j = 0; j <= 40; j++){//最后一个数可能的值
            for(int sum = j*n;sum <= 1600; sum++){//枚举可能的和
                ans += dp[n][j][1][sum] + dp[n][j][2][sum];
                ans %= mod;
            }
        }
      
       cout << ans << endl;
        system("pause"); 
        
    }

    参考:

    https://www.twblogs.net/a/5d494e75bd9eee5327fbc02d/zh-cn
    https://ac.nowcoder.com/acm/problem/blogs/21313

  • 相关阅读:
    HDU4311 Meeting point1 曼哈顿距离快速计算
    POJ1681 Painter's Problem 高消
    解决FLASH遮住DIV层的方法
    jcarousellite jQuery实现滚动的图片
    js中escape,encodeURI,encodeURIComponent三个函数的区别
    clear:both; 用法 什么时候用
    IE6下使网页png图片透明显示
    jqueryautocomplete 使用手册
    jquery获得select option的值 和对select option的操作
    jquery1.6获取checkbox的选中状态
  • 原文地址:https://www.cnblogs.com/Aliencxl/p/11954620.html
Copyright © 2020-2023  润新知