爱奇艺2019-笔试

两道题都是动态规划233。。。

1:

想法:

       我们看1 1 0, 我们先计算1 2 3满足1 1个数, 现在有来了一个4要求满足1 1 0;

       我们依次将1,2,3,4放在最后一位, 那么前三个数也可以看作一个排列;

       1 2 4 :3; (实际排列1 2  4和排列 1 2 3没有区别) 那么当3在最后一位时,我们只要得到

       前三位以3(相当于此时的4)结尾的合法数目即可。这样就得到了子问题的结构

  状态定义dp[i][j] :  (i+1)数字的排列满足前i个要求并以j结尾的合法数目

  状态转移: a[i]==1, 则x[i]>x[i+1]。dp[i][j]=sum dp[i-1][k]  (j<=k<=i)

                           a[i]==0, 则x[i]<x[i+1]。dp[i][j]=sum dp[i-1][k]  (1<=k<=j-1)

      为了进一步优化算法, 定义前缀和sum[i][j]=sum dp[i][k]  (1<=k<=j)

  时间复杂度O(n), 解决

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int N=1e3+7;
 5 const int mod=1e9+7;
 6 LL dp[N][N];
 7 LL sum[N][N];
 8 int a[N];
 9 int n;
10 int main()
11 {
12     cin>>n;
13     for (int i=1;i<n;i++) cin>>a[i];
14     if (a[1]) { dp[1][1]=1; sum[1][2]=sum[1][1]=1; }
15     else      { dp[1][2]=1; sum[1][2]=1; }
16     for (int i=2;i<n;i++) 
17         for (int j=1;j<=i+1;j++) {
18             if (a[i]) dp[i][j]=(sum[i-1][i]-sum[i-1][j-1]+mod)%mod;
19             else      dp[i][j]=sum[i-1][j-1];
20             sum[i][j]=(sum[i][j-1]+dp[i][j])%mod;
21         }
22     printf("%lld\n", sum[n-1][n]);
23     return 0;
24 }

2:

想法: 其实这道题我觉得很easy, 因为数据量并不大。

            对于n个红球,m个篮球,A赢的情况有这样3种:

          (1)A 先手抽中红球的概率

          (2)在A,B都抽中篮球的情况下

            2.1 C抽中红球之后A赢的概率

            2.2 C抽中篮球之后A赢的概率

            每一轮抽中之后,球的数量会减少,这就是一个动态规划问题

            状态定义:dp[n][m], n红m蓝 A赢的概率(不会递推, 只会递归。。。233)

        

猜你喜欢

转载自www.cnblogs.com/xidian-mao/p/11490392.html