第一题 P1616 疯狂的采药
没开longlong!!!基本就是跟着学长写的。。。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e7+10;
const int maxn1 = 1e4 + 10;
int w[maxn1];
int v[maxn1];
long long dp[2][maxn];
int main() {
int m;
int w0;
//w0背包大小
cin >> w0 >> m;
for (int i = 1; i <= m; i++) {
cin >> w[i] >> v[i];
}
int now=0,pre=0;
memset(dp[0], 0, sizeof(dp[0]));
for (int i = 1; i <= m; i++) {
now = i & 1;
pre = (i - 1) & 1;
dp[now][0] = 0;
for (int j = 1; j <= w0;j++) {
if (w[i] > j) {
dp[now][j] = dp[pre][j];
}
else {
dp[now][j] = max(dp[pre][j], dp[now][j - w[i]] + v[i]);
}
}
}
cout << dp[m & 1][w0];
}
第二题 P1833 樱花
普普通通的多重背包个屁,这是01和多重混在一起了,于是就塞了个判断进去,判断走那种方法,
#include<bits/stdc++.h>
using namespace std;
int n;
int dp[10010][1010];
const int maxn = 10000 + 100;
int w[maxn];
int v[maxn];
int c[maxn];
int main() {
int time1, time2, time3, time4, time;
char time5;
cin >> time1 >> time5 >> time2 >> time3 >> time5 >> time4;
time = (time3 - time1 - 1) * 60 + 60 - time2 + time4;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i] >> v[i] >> c[i];
}
memset(dp[0], 0, sizeof(dp[0]));
for (int i = 1; i <= n; i++) {
int now = i & 1;
int pre = (i - 1) & 1;
for (int j = 0; j <= time; j++) {
if (c[i] == 0) {
if (w[i] <= j) {
dp[now][j] = max(dp[pre][j], dp[now][j - w[i]] + v[i]);
}
else {
dp[now][j] = dp[pre][j];
}
}
if (c[i] == 1)
if (w[i] <= j) {
dp[now][j] = max(dp[pre][j], dp[pre][j - w[i]] + v[i]);
}
else {
dp[now][j] = dp[pre][j];
}
if (c[i] > 1) {
for (int k = 0; k <= c[i] && w[i] * k <= j; k++) {
dp[now][j] = max(dp[pre][j], dp[pre][j - k * w[i]] + v[i] * k);
}
}
}
}
cout << dp[n&1][time];
}
第三题 P1077 [NOIP2012 普及组] 摆花
方程:dp[i][j] = dp[i][j] + dp[i - 1][j - k],稳得一批;
i是当前讨论的花,k是这种花放几朵
则转k次循环,和j相等就停止
dp=当前情况已知的种数+不放该花并且空出k个空的种数。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100+5, b = 1000007;
int n, m, a[maxn], dp[maxn][maxn];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
dp[0][0] = 1;
for (int i = 1; i <= n; i++)
for (int j = 0; j <= m; j++)
for (int k = 0; k <= min(j, a[i]); k++)
dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % b;
cout << dp[n][m] << endl;
return 0;
}
第四题
写了个分组背包,应该,算吧。。。。
#include<bits/stdc++.h>
using namespace std;
struct wu
{
int v;
int w;
};
struct node2
{
int v, p, q, num;
}y[65];
vector<wu>h[100];
int dp[34010];
bool cmp(node2 a, node2 b)
{
return a.q < b.q;
}
int main()
{
int n, m, i, j, k;
int cnt = 0;
cin >> n >> m;
for (i = 1; i <= m; i++)
{
cin>>y[i].v>>y[i].p>>y[i].q;
y[i].num = i;
}
sort(y + 1, y + m + 1, cmp);
for (i = 1; i <= m; i++)
{
wu x;
if (y[i].q == 0)
{
x.v = y[i].v;
x.w = y[i].v * y[i].p;
h[y[i].num].push_back(x);
}
else
{
int s = h[y[i].q].size();
for (j = 0; j < s; j++)
{
x.v = y[i].v + h[y[i].q][j].v;
x.w = y[i].v * y[i].p + h[y[i].q][j].w;
h[y[i].q].push_back(x);
}
}
}
for (i = 1; i <= m; i++)
{
if (h[i].size() == 0) {
continue;
}
for (j = n; j >= 0; j--)
{
for (k = 0; k < h[i].size(); k++)
{
if (h[i][k].v <= j) dp[j] = max(dp[j], dp[j - h[i][k].v] + h[i][k].w);
}
}
}
cout << dp[n];
return 0;
}