(luogu P2113) 看球泡妹子
题目链接
https://www.luogu.org/problemnew/show/P2113
题解
几个月前尝试过的题。。现在终于a了
其实巨尼玛简单
就是一个01背包而且物品只能选k次
那么就再加一维不就行了
代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#define rg register int
#define ll long long
#define RG register
#define il inline
using namespace std;
il int gi() {
rg x=0,o=0;RG char ch=getchar();
while(ch!=‘-‘&&(ch<‘0‘||‘9‘<ch)) ch=getchar();
if(ch==‘-‘) o=1,ch=getchar();
while(‘0‘<=ch&&ch<=‘9‘) x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar();
return o?-x:x;
}
#define N 110
#define M 110
int n,m,K,C,ans;
int a[N],b[N],c[M],w[M],sum[M];
int f[N][M][M*20];
// 实际上就是只选 k 个物品的背包嘛 。。。
int main() {
n=gi(),m=gi(),K=gi(),C=gi();
for(rg i=1;i<=n;++i) a[i]=gi();
for(rg i=1;i<=n;++i) b[i]=gi();
for(rg p,q,i=1;i<=m;++i) {
p=gi(),q=gi();
w[i]=b[p]+b[q];
c[i]=a[p]*a[q];
sum[i]=sum[i-1]+w[i];
}
#define Getmax(a,b) (a)=(a)>(b)?(a):(b)
for(rg i=1;i<=m;++i)
for(rg j=1;j<=min(i,K);++j)
for(rg l=sum[i];l>=0;--l){
f[i][j][l]=f[i-1][j][l];
if(l>=w[i]&&(f[i-1][j-1][l-w[i]]>0||l==w[i]))
Getmax(f[i][j][l],f[i-1][j-1][l-w[i]]+c[i]);
if(l>=C) Getmax(ans,f[i][j][l]);
}
ans?printf("%d",ans):puts("-1");
return 0;
}