202104-4 校门外的树


思路:

这道题用DP是肯定的。但是应该从1维DP开始看起,这里的数据ai表示1e5也说明了使用二维DP是不行的。使用一维DP,用f[i]表示a0~a[i]的所有选法数量.状态分割为所有最后一个区间的左端点,这样就可以作到不重不漏

反思:

这道题其实讲实话不算难,但是自己在考场上以现在的熟练度应该还是很难写出来,估计就是10分走人的样子。自己的思路只能说状态表示想对了,但是状态划分不对,有了太多的重合。所以以后写DP还是这样想:状态标识-》状态划分-》状态转移方程。

#include 
#include 
#include 
#include 
using namespace std;
const int N = 1005;
const int M = 1e5 + 5;
const int MOD = 1e9 + 7;
bool st[M];
int f[N];
vector<int> q[M];
int a[N];
int n;
int main(){
    for(int i = 1;i){
        for(int j = 2 * i;j < M;j += i){
            q[j].push_back(i);
        }
    }
    scanf("%d", &n);
    for(int i = 0;i){
        scanf("%d", &a[i]);
    }
    f[0] = 1;
    for(int i = 1;i){
        memset(st, false, sizeof(st));
        for(int j = i - 1;j >= 0;j--){
            int d = a[i] - a[j];
            int cnt = 0;
            for(auto t : q[d]){
                if(!st[t]){
                    cnt++;
                    st[t] = true;
                }
            }
            st[d] = true;
            f[i] = (f[i] + (long long)f[j] * cnt) % MOD;
        }
    }
    cout<1]<<endl;
    return 0; 
}
csp