因为太懒所以不想写博客,但为了应付一下自己还是写写
问题描述(来自AcWing)
问题解决
暴力求法
1 别想真从我这学到东西,不如去AcWing
#include<iostream>
using namespace std;
int n, m;
int v[10010];
int w[10010];
int f[10010][10010];
int g[10010];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> v[i] >> w[i];
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
for (int k = 0; k * v[i] <= j; k++)
{
f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);
}
}
}
cout << f[n][m];
return 0;
}
2 优化方法
通过上述地推公式,可以优化一层循环,代码如下
#include<iostream>
using namespace std;
int n, m;
int v[10010];
int w[10010];
int f[10010][10010];
int g[10010];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> v[i] >> w[i];
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
if (j - v[i] >= 0)
f[i][j] = max(f[i - 1][j], f[i][j - v[i]] + w[i]);
else f[i][j] = f[i - 1][j];
}
}
cout << f[n][m];
return 0;
}
通过观察可以发现每一层的状态只与f[i - 1][j]和f[i][j - v[i]]有关,与i-2,i-3到第一层无关,此时可以优化一维数组,代码如下
#include<iostream>
using namespace std;
int n, m;
int v[10010];
int w[10010];
int f[10010];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> v[i] >> w[i];
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
if (j - v[i] >= 0)
/*f[i][j] = max(f[i - 1][j], f[i][j - v[i]] + w[i]);*/
f[j] = max(f[j], f[j - v[i]] + w[i]);
else f[j] = f[j];
}
}
cout << f[m];
return 0;
}
总结:
好了今天的博客水完了,不喜欢的别滑走,可以点踩