这道题,我乱写。。题都读错了,没看到q,p只能在两个不同的取。错误算法还对(100)了。
正解:
f[i][j]:表示第i个数,q有j个没有匹配,的p没有匹配数.
二分总答案数。只要最后满足f[1+n][mid] >= mid 就好,处理完n个数,q有mid个没有匹配,p有大于等于mid个没有匹配.一定可以匹配出mid个。
对于第i个数,如果它可以分成的p的数量和q 的数量之和大于总答案数,肯定i不能分成这么多个,分成这么多个的话会自己和自己配对,转移时保证p的数量和q 的数量之和小于等于总答案数。
标程:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 55, maxm = 2222;
int f[maxn][maxm], b[maxn], c[maxn][maxn], a[maxn], p1, p2;
int main()
{
int i, j, ll = 0, rr = 0, mid, ft, k, n;
scanf("%d", & n);
for (i = 0; i < n; ++i) scanf("%d", & a[i]);
scanf("%d%d", & p1, & p2);
for (i=0;i<n;i++)
{
b[i] = a[i]/p1;
for (j=0;j<=b[i];j++) c[i][j] = (a[i]-j*p1)/p2;
}
for (i=0;i<n;i++) rr += a[i];
rr /= (p1+p2);
while (ll < rr)
{
mid = (ll+rr+1) >> 1;
memset(f,255,sizeof(f));
f[0][0] = 0;
for (i=0;i<n;i++)
for (j=0;j<=40*i;j++) if (f[i][j] >= 0)
for (k=0;k<=b[i] && k<=mid;k++)
{
ft = c[i][k];
if (ft > mid-k) ft = mid-k;
ft += f[i][j];
if (ft > f[i+1][j+k]) f[i+1][j+k] = ft;
}
if (f[n][mid] >= mid) ll = mid;
else rr = mid-1;
}
cout << ll*(p1+p2) << endl;
}
我自己的乱做狗分代码。
#include<bits/stdc++.h>
using namespace std;
int n, a[55], dp[55][100004], p, q, sum[55];
void read(int &x)
{
x = 0; int ff = 0; char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-') ff = 1; c = getchar();
}
while(c >= '0' && c <= '9')
{
x = x * 10 + c - '0'; c = getchar();
}
if(ff) x = -x;
}
int main()
{
freopen("pq.in","r",stdin);
freopen("pq.out","w",stdout);
read(n);
for(int i = 1; i <= n; i++)
{
read(a[i]);
sum[i] = a[i] + sum[i-1];
}
read(p); read(q);
if(p > q) swap(p,q);
for(int i = 1; i <= n; i++)
{
int k = a[i] / q;
for(int j = 0; j <= k; j++)
{
int he = a[i] - j * q;
int ha = he / p;
int hi = max(0, j - ha);
if(hi == 0) dp[i][abs(j-ha)] = j;
int hehe = sum[i-1] / p;
if(ha <= j)
for(int z = hi; z <= hehe; z++)
{
dp[i][z - hi] = max(dp[i][z - hi],dp[i-1][z] + j);
}
if(ha > j)for(int z = 0; z <= hehe; z++) dp[i][z+ha - j] = max(dp[i][z+ha - j],dp[i-1][z] + j);}
}
int ans = 0;
for(int i = 0; i <= sum[i] / p; i++)
{
ans = max(dp[n][i],ans);
}
cout << ans * (p + q);
return 0;
}
附上题解=、=
看不懂他们发的题解的我。