2/13 复习下背包+单调队列变型
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2/13 复习下背包+单调队列变型相关的知识,希望对你有一定的参考价值。
回过头来看这些背包和贪心,发现简单了不少……qaq
简单的01背包求方案数:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e4+5;;
int v,n,a[30],f[maxn];
signed main()
scanf("%lld%lld",&v,&n);
for(int i=1;i<=v;i++)
scanf("%lld",&a[i]);
f[0]=1;
for(int i=1;i<=v;i++)
for(int j=a[i];j<=n;j++)
f[j]=f[j]+f[j-a[i]];
cout<<f[n]<<endl;
return 0;
https://www.luogu.com.cn/problem/P1586
多增加了一个维度:用到了几个数构成了这个结果
f[i][j]:表示数字i用了j个数构成
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+5;
const int M=32768;
int t,n,f[maxn][5];
signed main()
f[0][0]=1;
for(int i=1;i*i<=M;i++)
for(int j=i*i;j<=M;j++)
for(int k=1;k<=4;k++)
f[j][k]+=f[j-i*i][k-1];
scanf("%lld",&t);
while(t--)
int n,tmp=0;
scanf("%lld",&n);
for(int i=1;i<=4;i++)
tmp+=f[n][i];
cout<<tmp<<endl;
return 0;
https://www.luogu.com.cn/problem/P1638
不断更新左端点的值,就是左端点最后出现的位置如果大于左端点,则left++
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
int pos[2005],p[maxn],n,m,k;
signed main()
scanf("%lld%lld",&n,&m);
memset(pos,-1,sizeof(pos));
int l=1,ll=0,rr=0,ml=inf;
for(int i=1;i<=n;i++)
scanf("%lld",&p[i]);
if(pos[p[i]]==-1)
k++;
pos[p[i]]=i;
while(l!=i&&l<pos[p[l]])
l++;
if(k==m&&i-l+1<ml)
ml=i-l+1;
ll=l;
rr=i;
//cout<<ml<<endl;
cout<<ll<<" "<<rr<<endl;
return 0;
以上是关于2/13 复习下背包+单调队列变型的主要内容,如果未能解决你的问题,请参考以下文章