POJ - 2586 - Y2K Accounting Bug = 枚举
http://poj.org/problem?id=2586
迷惑的英文,什么乱来的,就算是中文也看不懂啊。北大果然nb。
题意:
每个月会给出一个财务报告:赢利或者亏空 如果赢利则赢利s,如果亏空则亏空d
(12个月都一样,只有赢利s或者亏空d两种情况)
每五个月也会给出一个报告(1~5 ,2~6 。。。)一年一共有8次这样的报告,已知这8次都报告亏空
问整年情况:如果亏空则输出Deficit,如果赢利,输出整年可能赢利的最大值
来源:http://poj.org/showmessage?message_id=114669
所以就是枚举12个月的s或d的状态,使得每个大段都亏空的就更新答案。
注意不要演,12-5=7,但上界并不是7,而是8!因为是小于号。
加个剪枝才可以通过,否则就需要贪心了,贪心的话就优先把s月放在两端。
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<stack>
#include<string>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
ll s, d;
bool check(int u) {
for(int i = 0; i < 8; ++i) {
ll sum = 0;
for(int j = 0; j < 5; ++j) {
if((u >> (i + j)) & 1) {
sum += s;
} else {
sum -= d;
}
}
if(sum > 0)
return false;
}
return true;
}
ll ans(int u, int &maxans1) {
ll sum = 0;
maxans1 = 0;
for(int i = 0; i < 12; ++i) {
if((u >> i) & 1) {
sum += s;
++maxans1;
} else {
sum -= d;
}
}
return sum;
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
while(~scanf("%lld%lld", &s, &d)) {
ll maxans = -1e18;
int maxans1 = 0;
for(int i = 0; i < (1 << 12); ++i) {
int cur = 0;
for(int j = 0; j < 12; ++j) {
if((i >> j) & 1) {
cur++;
}
}
if(cur <= maxans1)
continue;
if(check(i)) {
maxans = max(maxans, ans(i, maxans1));
}
}
if(maxans > 0)
printf("%lld\n", maxans);
else
puts("Deficit");
}
}
假如可以用奇怪的函数说不定会更快。
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<stack>
#include<string>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
int s, d;
bool check(int u) {
for(int i = 0; i < 8; ++i) {
int sum = 0;
for(int j = 0; j < 5; ++j) {
if((u >> (i + j)) & 1) {
sum += s;
} else {
sum -= d;
}
}
if(sum > 0)
return false;
}
return true;
}
int ans(int u, int &maxans1) {
int sum = 0;
maxans1 = 0;
for(int i = 0; i < 12; ++i) {
if((u >> i) & 1) {
sum += s;
++maxans1;
} else {
sum -= d;
}
}
return sum;
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
while(~scanf("%d%d", &s, &d)) {
int maxans = -1e9;
int maxans1 = 0;
for(int i = (1 << 12) - 1; i >= 0; --i) {
int cur = 0;
for(int j = 0; j < 12; ++j) {
if((i >> j) & 1) {
cur++;
}
}
if(cur <= maxans1)
continue;
if(check(i)) {
maxans = max(maxans, ans(i, maxans1));
}
}
if(maxans > 0)
printf("%d\n", maxans);
else
puts("Deficit");
}
}
最大的一定是
++++++++++++
但它不可能亏损
加入亏损的话,按道理应该尽可能使亏损的覆盖面大,也就是
假如只需要亏损1次:
++++-++++-++
假如亏损2次:
+++--+++--++
假如亏损3次:
++---++---++
假如亏损4次 :
+----+----+-