P & Q(dp)

P & Q(dp)

这道题,我乱写。。题都读错了,没看到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;
}

附上题解=、=

P & Q(dp)

看不懂他们发的题解的我。

相关文章:

  • 2022-02-15
  • 2022-01-25
  • 2022-01-17
  • 2021-05-31
  • 2021-05-27
  • 2021-12-03
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-10-19
  • 2022-12-23
  • 2021-12-06
  • 2022-12-23
  • 2022-12-23
  • 2021-11-04
  • 2021-12-06
相关资源
相似解决方案