F - Knapsack for All Segments
题意
给你一个长度为n的数组,求任意[ L,R ]区间和为S的总数。
思路
01背包DP变形
求一个范围内的值域为某个数。
首先我们想到01背包求能恰好能装满背包时和这个的区别在于,这个求和还要包括 [2,i]、[3,i]、[4,i]、…、[i,i]这些情况,所以要让 f[0]++,因为每次可以取到0的方***多一种。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 998244353;
const ll maxn = 1e6 + 5;
const int N = 3050;
ll n,s,a[N],f[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>s;
for(int i=1;i<=n;i++){
cin>>a[i];
}
ll res=0;
for(int i=1;i<=n;i++){
f[0]++;
for(int j=s;j>=a[i];j--){
f[j]=(f[j]+f[j-a[i]])%mod;
}
res=(res+f[s])%mod;
}
cout<<res<<'\n';
return 0;
}