线性dp。
·状态表示:
设f[j]表示,在符合贴布告要求下,刚好满前j个布告位置用的最少布告。
·状态状态转移方程:
由第 i张布告必须要覆盖掉布告板的第 i 个位置,布告不能够相互重叠,但是可以紧贴,可知:
对于i>j,i<j+a[i]时,有:
f[j+a[i]]=min(f[j+a[i]],f[j]);
然后从前往后递推即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
const int p=1e9+7;
const int N=5e3+10;
int f[N];
int a[N];
void solve()
{
memset(f,0x3f,sizeof f);// f[j+a[i]]=(f[j+a[i]],f[j]+1) j<i&&i<=j+a[i]
int n; cin>>n;
f[0]=0;
for(int i=1;i<=n;i++)
{
int x; cin>>x;
for(int j=0;j<i;j++)
if(i<=j+x)
f[j+x]=min(f[j+x],f[j]+1);
}
cout<<(f[n]<=5000?f[n]:-1)<<endl;
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
// t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
24/8/5