CSP第22次 202104-4 校门外的树 C语言答案

CSP第22次 202104-4 校门外的树 C语言60分答案

CSP第22次 202104-4 校门外的树 C语言答案

先讲一下思路:

数组 arr[i] 记录每个障碍物的位置,arr[1] 即第一个障碍物的位置
数组 dp[i][j] 记录第 i 个障碍物到第 j 个障碍物的方案数(内部不组合!!!)
数组 count[i] 记录前 i 个障碍物总的方案数

那么count[i]可以这么求
count[1] = 1
count[2] = dp[1][2]
count[3] = dp[1][3]     +dp[1][2]*dp[2][3]
count[4] = dp[1][4]     +dp[1][2]*dp[2][4] +dp[1][3]*dp[3][4]     +dp[1][2]*dp[2][3]*dp[3][4]
count[5] = dp[1][5]     +dp[1][2]*dp[2][5] +dp[1][3]*dp[3][5] +dp[1][4]*dp[4][5]     +dp[1][2]*dp[2][3]*dp[3][5] +dp[1][2]*dp[2][4]*dp[4][5] +dp[1][3]*dp[3][4]*dp[4][5]     +dp[1][2]*dp[2][3]*dp[3][4]*dp[4][5]
仅仅调整一下相加的顺序,方便大家观察
count[1] = 1
count[2] = dp[1][2]
count[3] = dp[1][3]     +dp[1][2]*dp[2][3]
count[4] = dp[1][4]     +dp[1][2]*dp[2][4]     +dp[1][3]*dp[3][4] +dp[1][2]*dp[2][3]*dp[3][4]
count[5] = dp[1][5]     +dp[1][2]*dp[2][5]     +dp[1][3]*dp[3][5] +dp[1][2]*dp[2][3]*dp[3][5]     +dp[1][4]*dp[4][5] +dp[1][2]*dp[2][4]*dp[4][5] +dp[1][3]*dp[3][4]*dp[4][5] +dp[1][2]*dp[2][3]*dp[3][4]*dp[4][5]
将dp[][]尽可能地替换成count后
count[1] = 1
count[2] = count[1]*dp[1][2]
count[3] = count[1]*dp[1][3]     +count[2]*dp[2][3]
count[4] = count[1]*dp[1][4]     +count[2]*dp[2][4]     +count[3]*dp[3][4]
count[5] = count[1]*dp[1][5]     +count[2]*dp[2][5]     +count[3]*dp[3][5]     +count[4]*dp[4][5]

以上就是本题动态规划的状态转移公式了
是不是很神奇!我研究了好长时间才想清楚,所以为了方便各位理解我这里详细地把式子的变化过程都敲出来了,点个赞就当劳动费吧哈哈

//纯C语言60分代码
#include <stdio.h>

int arr[1010];//记录每个障碍物的坐标
int obstacle[100010]={0};//标记哪些点是障碍物
long long dp[1010][1010];//第 a 个障碍物到第 b 个障碍物的方案数(内部不组合!!!)
long long ans[1010]={0};//前 i 个障碍物总的方案数
const int mod = 1e9 + 7;

int computeDp(int a,int b)//求第 a 个障碍物到第 b 个障碍物的方案数(内部不组合!!!)
{
    int i,j,difference=arr[b]-arr[a],count=0;
    for(i=1;i<difference;i++)//这里i为间隔多少
        for(j=arr[a]+i;j<=arr[b];j+=i)
        {
            if(j==arr[b])
                count++;
            if(obstacle[j])
                break;
        }
    return count;
}

int main()
{
    int n,i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++)//读取arr并记录obstacle
    {
        scanf("%d",&arr[i]);
        obstacle[arr[i]]=1;
    }
    for(i=1;i<n;i++)//求dp
        for(j=i+1;j<=n;j++)
        {
            dp[i][j] = computeDp(i,j);
        }
    ans[1] = 1;
    for(i=2;i<=n;i++)//求ans[i]
        for(j=1;j<i;j++)
            ans[i] = (ans[i]%mod + ans[j]*dp[j][i]%mod)%mod;
    printf("%lld",ans[n]);
    return 0;
}

上一篇:202104-2 邻 域 均 值


下一篇:202104-1 灰度直方图