zoukankan      html  css  js  c++  java
  • 洛谷 P4933 大师(dp)

    传送门


    解题思路

    设dp[i][j]表示选出了第i个电塔,上一个选出的是第j个电塔的方案数。

    枚举i,j,转移方程为:

      找一个k,使得h[k],h[j],h[i]构成等差数列,并且k<j。

      dp[i][j]+=dp[j][k];

    对于确定的i,j,h[k]是确定的,所以我们可以用vector a[i]的高度为i的编号,k即为枚举a[h[k]]里的元素。

    为了防止快乐的RE,

    要判断计算出的h[k]是否<0或者>=maxv。

    时间复杂度不太会算,看起来像是在O(n^2)到O(n^3)之间,貌似重复元素个数不同时间不同……

    有大佬知道的麻烦在评论区留言,万分感谢~

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<vector>
     7 using namespace std;
     8 const int maxn=1005;
     9 const int maxv=20005;
    10 const int mod=998244353;
    11 int n,h[maxn],dp[maxn][maxn],ans;
    12 vector<int> a[maxv];
    13 int main()
    14 {
    15     cin>>n;
    16     ans=n;
    17     for(int i=1;i<=n;i++) cin>>h[i];
    18     for(int i=1;i<=n;i++) {
    19         for(int j=1;j<i;j++){
    20             dp[i][j]=1;
    21             int d=h[i]-h[j];
    22             if(h[j]-d<0||h[j]-d>=maxv){
    23                 ans=(ans+1)%mod;
    24                 continue;
    25             }
    26             for(int k=0;k<a[h[j]-d].size();k++){
    27                 if(a[h[j]-d][k]>=j) break;
    28                 else dp[i][j]=(dp[i][j]+dp[j][a[h[j]-d][k]])%mod;
    29             }
    30             ans=(ans+dp[i][j])%mod;
    31         }
    32         a[h[i]].push_back(i);
    33     }
    34     cout<<ans;
    35     return 0;
    36 }

    //明天还上课,困死了,睡觉睡觉………… 

  • 相关阅读:
    Python3 调用 Ansible2.x API
    Django——form组件和ModelForm
    Python super().__init__()测试及理解
    ORACLE迁移记录
    CentOS7安装zabbix5.0
    ORACLE LINUX 7.7 安装ORACLE 11.2.0.4.0 RAC
    Spring
    【Git】clone项目&push项目没反应,Cloning into...没下载
    样式不显示,静态资源路径错误
    日常Java练习题
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13829520.html
Copyright © 2011-2022 走看看