明明是一道水题好么。。。
题意是有两种货物,一种占用1单位面积,另一种占用2单位面积
每个货物有对应的价值
现在有n个货物,总面积为v,问如何能够使所载货物价值最大
很明显的背包问题
但是因为要打印路径,感觉直接排序写起来比较方便
我的思路是按不同面积排序,每次比较两种情况的价值,取较大者
我的思路是对的,可能是题目时间太久的原因,莫名其妙地RE
把RE代码贴在这里,希望发现问题的人可以讲解一下:
/* ***********************************************
Author : yinwoods
E-Mail : yinwoods@163.com
Created Time : 2014年12月28日 星期日 16时55分40秒
File Name : 3B.cpp
************************************************ */
#include <vector>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 200010
#define LL long long
using namespace std;
struct T_T {
int p, id;
}a1[MAXN], a2[MAXN];
int res[MAXN];
bool cmp(T_T a, T_T b) {
if(a.p >= b.p) return true;
return false;
}
int main() {
memset(a1, 0, sizeof(a1));
memset(a2, 0, sizeof(a2));
int n, v, cnt1, cnt2, cnt3, t, p;
scanf("%d%d", &n, &v);
cnt1 = cnt2 = cnt3 = 0;
for(int i=0; i<n; ++i) {
scanf("%d%d", &t, &p);
if(t == 1) {
a1[cnt1].id = i+1;
a1[cnt1++].p = p;
} else {
a2[cnt2].id = i+1;
a2[cnt2++].p = p;
}
}
sort(a1, a1+cnt1, cmp);
int ans = 0;
int j, k;
j = k = 0;
sort(a2, a2+cnt2, cmp);
int last_id = -1;
int last_cnt3 = -1;
while(v > 1) {
if(k >= cnt1) {
k = cnt1;
if(j >= cnt2)
break;
}
if(a2[j].p >= a1[k].p+a1[k+1].p) {
ans += a2[j].p;
res[cnt3++] = a2[j].id;
++j;
v -= 2;
} else {
ans = ans+a1[k].p+a1[k+1].p;
res[cnt3++] = a1[k].id;
--v;
if(k+1 < cnt1) {
res[cnt3++] = a1[k+1].id;
last_id = k+1;
last_cnt3 = cnt3-1;
k += 2;
--v;
} else if(k < cnt1) {
last_id = k;
last_cnt3 = cnt3-1;
++k;
}
}
//printf("v = %d\tans = %d\n", v, ans);
}
//printf("k = %d\n", k);
//printf("v = %d\n", v);
if(v && k<cnt1) {
if(last_id!=-1 && a1[k].p+a1[last_id].p>a2[j].p) {
ans += a1[k].p;
res[cnt3++] = a1[k].id;
--v;
}
}
if(v) {//如果最后还有一个单位空着,考虑是否用一个占用2单位面积的货物来替换
if(last_id!=-1 && j<cnt2) {
ans -= a1[last_id].p;
ans += a2[j].p;
res[last_cnt3] = a2[j].id;
}
}
printf("%d\n", ans);
for(int i=0; i<cnt3; ++i)
printf("%d ", res[i]);
puts("");
return 0;
}
可能是数组大小的问题吧,后来看了别人的用STL写了一份代码
如下:
/* ***********************************************
Author : yinwoods
E-Mail : yinwoods@163.com
Created Time : 2014年12月28日 星期日 16时55分40秒
File Name : 3B.cpp
************************************************ */
#include <vector>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 100010
#define LL long long
using namespace std;
vector< pair<int, int> > a;
vector< pair<int, int> > b;
vector< pair<int, int> > ans;
bool cmp(pair<int, int> x, pair<int, int> y) {
return x.second > y.second;
}
int main() {
int n, v, t, p;
scanf("%d%d", &n, &v);
for(int i=0; i<n; ++i) {
scanf("%d%d", &t, &p);
if(t == 1) {
a.push_back(make_pair(i+1, p));
} else {
b.push_back(make_pair(i+1, p));
}
}
sort(a.begin(), a.end(), cmp);
sort(b.begin(), b.end(), cmp);
int cnt2 = 0;
while(v>1 && cnt2<b.size()) {
ans.push_back(b[cnt2]);
v -= 2;
++cnt2;
}
int lst = ans.size()-1;
int cnt1 = 0;
while(v>0 && cnt1<a.size()) {
ans.push_back(a[cnt1]);
--v;
++cnt1;
}
for(; cnt1<a.size()-1 && lst>=0; cnt1+=2) {
if(a[cnt1].second + a[cnt1+1].second > ans[lst].second) {
ans.erase(ans.begin() + lst);
ans.push_back(a[cnt1]);
ans.push_back(a[cnt1+1]);
--lst;
}
}
if(lst >= 0 && cnt1==a.size()-1) {
if(a[cnt1].second > ans[lst].second) {
ans.erase(ans.begin() + lst);
ans.push_back(a[cnt1]);
--lst;
}
}
if(ans.size() > 0) {
int res = 0;
for(int i=0; i<ans.size(); ++i)
res += ans[i].second;
printf("%d\n", res);
for(int i=0; i<ans.size(); ++i) {
printf("%d ", ans[i].first);
}
puts("");
} else puts("0");
return 0;
}