dp这一类的题目前都没有很好的把握,特意开个专栏来记录做的dp题,希望十天能有一定的进步!!(因为时间比较紧,所以我的文章只是记录自己的做题情况以及遇到疑惑的求助,并没有涉及题解思路什么的)
校门外的树这道题主要涉及到其中方案数的组合,最开始摸不着头脑,后面看了很久满分题解,最终明白了思路,把代码放着记录一下。
//2104-4校门外的树
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9+7;
vector<int> yue[100005]; // 记录不同长度的约数因子
int a[1005]; // 记录树的位置
int f[1005]; // 记录到第i个障碍物的总方案数
bool flag[100005]; // 记录约数使用情况,每次计算不同时需要重置清零
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n;
cin >> n;
for(int i=0; i<n; i++) {
cin >> a[i];
}
// 计算约数----存入表中
for(int i=1; i<100005; i++) { // 查找约数为i对应的整数
for(int j=2*i; j<100005; j+=i) {
yue[j].push_back(i);
}
}
f[0] = 1; // 设置初始值
for(int i=1; i<n; i++) {
memset(flag, 0, sizeof(flag)); // 清空状态数组
for(int j=i-1; j>=0; j--) {
int d = a[i] - a[j];
ll cnt = 0; // 方案数
for(int k=0; k<yue[d].size(); k++) {
int temp = yue[d][k];
if(!flag[temp]) {
cnt++; flag[temp]=true;
}
}
flag[d] = true; // 因为有障碍物,不能选
f[i] = (f[i]+f[j]*cnt)%mod;
}
}
cout << f[n-1] << endl;
return 0;
}