http://codeforces.com/contest/364
A. Matrix
考虑一个矩形(x, y, z, t)的sum和等于 (s[x] + s[x+1] + ... +s[y]) * (s[z] + s[z+1] + ... s[t]),所以处理出所有子序列的和即可,有些小细节要注意比如说0,比赛时候囧了。。
// Author : JayYe Created Time: 2013-11-19 23:47:55
#include
#include
#include
B. Free Market
一直不知道怎么处理好只能拿一个集合去交换没有交集的集合,其实对于两个不同的状态a, b,如果b - a <= d,那么必然可是由a状态一步转移到b状态,如果a、b没有交集,那就直接用a的集合换b的集合,如果有交集,其实不要交换相同元素即可。所以首先背包把所有的可行状态处理出来,然后每天贪心取到最多能取的 <= d的下一个状态,于是就这样解决了。。还是太弱了
// Author : JayYe Created Time: 2013-11-20 18:56:53
#include
#include
#include
using namespace std;
const int maxn = 1000000 + 10;
bool vis[maxn];
int b[maxn], a[55];
int main() {
int n, d;
scanf("%d%d", &n, &d);
for(int i = 1;i <= n; i++) {
scanf("%d", &a[i]);
}
sort(a + 1, a + n + 1);
vis[0] = true;
int pre = 0;
for(int i = 1;i <= n; i++) {
bool flag = false;
for(int j = pre;j >= 0; j--) if(vis[j] && a[i] - j <= d) {
flag = true;
break;
}
if(!flag) break;
for(int j = pre;j >= 0; j--) if(vis[j])
vis[j + a[i]] = true;
pre += a[i];
}
int tot = 0, ans = 0;
for(int i = 0;i <= pre;i ++) if(vis[i])
b[tot++] = i;
if(tot == 1) return puts("0 0"), 0;
pre = 0;
for(int i = 0;i < tot; i++) {
if(pre + d < b[i]) {
ans++; pre = b[i-1];
}
}
ans++;
printf("%d %d\n", b[tot-1], ans);
return 0;
}