2010 ACM-ICPC Multi-University Training Contest(2)——Host by BUPT 解题报告[部分]


 

Shift Number

分析:比赛中做出最多的一道,但也确实卡了很多大牛、菜鸟。推导的过程如下图:

 

1

3

6

6

5

3

1

2

3

 

 

 

 

1

2

3

 

 

 

 

1

2

3

 

 

 

 

1

2

3

 

 

等价于:

 

1

3

6

6

5

3

1

1

1

1

 

 

 

2

2

2

2

 

 

 

3

3

3

3

 

发现:1111,2222,3333都是1111的倍数,于是规律就可以看出来了。

 

代码
#include <stdio.h>
#include
<string.h>
#define LL __int64

int main()
{
LL x;
while (scanf("%I64d", &x) != EOF) {
if (!x) break;
LL k
= 1, t;
while (k < x) k = k*10+1;
k
/= 10;
while (x%k != 0) k /= 10;
printf(
"%I64d\n", x/k);
}
return 0;
}

 

 

Bag Problem

分析:背包。数据范围比较大,用set+map水过。后来birdfly出了一组很BT的数据,把我的程序给cha掉了。呜~

 

代码
#include <stdio.h>
#include
<string.h>
#include
<set>
#include
<map>
using namespace std;

int main()
{
int n, m, k, i;
int gd[41];
// freopen("in.txt", "r", stdin);
set<int, greater<int> > mp, mp1;
map
<int, int> bg;
while (scanf("%d%d", &n, &m) != EOF) {
scanf(
"%d", &k);
for (i=0; i<k; i++) {
scanf(
"%d", &gd[i]);
}
mp.clear();
mp1.clear();
bg.clear();
mp.insert(
0);
bg[
0] = 0;
mp1
= mp;
int w;
set<int, greater<int> >::iterator it;
for (i=0; i<k; i++) {
it
= mp.begin();
while (it != mp.end()) {
w
= *it;
if (w+gd[i] <= m && bg[w] < n) {
mp1.insert(w
+gd[i]);
bg[w
+gd[i]] = bg[w]+1;
}
it
++;
}
mp
= mp1;
}
it
= mp.begin();
int max=*it;

printf(
"%d\n", max);
}
return 0;
}

 

 

Consumer

分析:背包。题目原型是 USACO DEC09 vidgame,不再赘述。

 

Counting Sequences

分析:DP+树状数组优化。刚好最近在学树状数组,不过跟DP结合来用还是第一次,当然是参考了别人的解题报告

dp方程很明显, dp[i] = dp[i-1]+A, dp[i]:前i个元素的 Perfect Sub-sequences 的个数,A为以第i个元素为结尾的Perfect Sub-sequences

的个数。为了求 A,可以先将元素离散化,不用处理重复的情况。f[i] 就表示 以i结尾的Perfect Sub-sequences的个数,包括单独的i(求和的需要,也是不处理重复情况的原因)。

 

代码
#include <stdio.h>
#include
<string.h>
#include
<algorithm>
using namespace std;
#define NL 100001
#define MD 9901

struct Num {
int a, id;
bool operator < (const Num &x) const {
return a < x.a;
}
}ent[NL];
int b[NL], dp[NL], t[NL];
int n, d;

inline
int lowbit(int x)
{
return x&(-x);
}

int sum(int x)
{
int cnt = 0;
while (x > 0) {
cnt
+= t[x];
x
-= lowbit(x);
}
return cnt;
}

void update(int x, int c)
{
while (x <= n) {
t[x]
+= c;
x
+= lowbit(x);
}
}

int find(int x)
{
int low = 1, high = n, mid;
int ans = 0;
while (low <= high) {
mid
= (low+high)>>1;
if (ent[mid].a > x) {
high
= mid-1;
}
else {
ans
= mid;
low
= mid+1;
}
}
return ans;
}

int main()
{
int i, j;
// freopen("in.txt", "r", stdin);
while (scanf("%d%d", &n, &d) != EOF) {
for (i=1; i<=n; i++) {
scanf(
"%d", &ent[i].a);
ent[i].id
= i;
}
sort(ent
+1, ent+1+n);
b[ent[
1].id] = 1;
for (i=2; i<=n; i++) {
b[ent[i].id]
= i;
}
dp[
1] = 0;
memset(t,
0, sizeof(t));
update(b[
1], 1);
for (i=2; i<=n; i++) {
int k1 = find(ent[b[i]].a+d);
int k2 = find(ent[b[i]].a-d-1);
int inc = sum(k1)-sum(k2);
inc
= (inc+MD)%MD;
dp[i]
= (dp[i-1]+inc)%MD;
update(b[i], inc
+1);
}
printf(
"%d\n", dp[n]);
}
return 0;
}

 





1

3

6

6

5

3

1

2

3

 

 

 

 

1

2

3

 

 

 

 

1

2

3

 

 

 

 

1

2

3

posted @ 2010-08-12 12:26  superbin  阅读(454)  评论(0编辑  收藏  举报