【 2013 Multi-University Training Contest 4 】

HDU 4632 Palindrome subsequence

dp[x][y]表示区间[x,y]构成回文串的方案数。

若str[x]==str[y],dp[x][y]=dp[x+1][y]+dp[x][y-1]-dp[x+1][y-1]+(dp[x+1][y-1]+1)=dp[x+1][y]+dp[x][y-1]+1。

若str[x]!=str[y],dp[x][y]=dp[x+1][y]+dp[x][y-1]-dp[x+1][y-1]。

 1 #include<cstdio>

 2 #include<cstring>

 3 #define MAXN 1010

 4 #define MOD 10007

 5 char str[MAXN];

 6 int dp[MAXN][MAXN];

 7 int dfs(int x, int y) {

 8     if (dp[x][y] == -1) {

 9         if (str[x] != str[y]) {

10             dp[x][y] = dfs(x + 1, y) + dfs(x, y - 1) - dfs(x + 1, y - 1);

11         } else {

12             dp[x][y] = dfs(x + 1, y) + dfs(x, y - 1) + 1;

13         }

14     }

15     dp[x][y] %= MOD;

16     return dp[x][y];

17 }

18 int main() {

19     int T;

20     int ca = 1;

21     int len;

22     int i;

23     scanf("%d", &T);

24     while (T--) {

25         memset(dp, -1, sizeof(dp));

26         scanf(" %s", str);

27         len = strlen(str);

28         for (i = 0; i < len; i++) {

29             dp[i][i] = 1;

30         }

31         for (i = 1; i < len; i++) {

32             if (str[i] == str[i - 1]) {

33                 dp[i - 1][i] = 3;

34             } else {

35                 dp[i - 1][i] = 2;

36             }

37         }

38         printf("Case %d: %d\n", ca++, (dfs(0, len - 1) + MOD) % MOD);

39     }

40     return 0;

41 }
View Code

 


 

HDU 4633 Who's Aunt Zhang

由Polya得到:

本身到本身的置换有1种,k8+12+54

沿着一个面的中心旋转90度有3种,k(1+1+3)*(1+1+3)+1+9

沿着一个面的中心旋转270度有3种,k(1+1+3)*(1+1+3)+1+9

沿着一个面的中心旋转180度有3种,k(2+2+5)*(2+2+5)+2+18

沿着正方体的两个对顶点旋转120度有4种,k2+2+9+9+2+2

沿着正方体的两个对顶点旋转240度有4种,k2+2+9+9+2+2

沿着正方体的中心,与正方体任意两条对边的中点旋转180度有6种,k4+8+18+8

 1 #include<cstdio>

 2 #define MOD 10007

 3 int powmod(int a, int b) {

 4     int ans;

 5     for (ans = 1; b; b >>= 1) {

 6         if (b & 1) {

 7             ans *= a;

 8             ans %= MOD;

 9         }

10         a *= a;

11         a %= MOD;

12     }

13     return ans;

14 }

15 int ext_gcd(int a, int b, int &x, int &y) {

16     int t, d;

17     if (b == 0) {

18         x = 1;

19         y = 0;

20         return a;

21     }

22     d = ext_gcd(b, a % b, x, y);

23     t = x;

24     x = y;

25     y = t - a / b * y;

26     return d;

27 }

28 

29 int Invmod(int a, int n) {

30     int x, y;

31     if (ext_gcd(a, n, x, y) != 1)

32         return -1;

33     return (x % n + n) % n;

34 }

35 int main() {

36     int T;

37     int ca = 1;

38     int n;

39     int ans;

40     scanf("%d", &T);

41     while (T--) {

42         scanf("%d", &n);

43         ans = powmod(n, 8 + 12 + 54);

44         ans += 6 * powmod(n, 20);

45         ans += 3 * powmod(n, 38);

46         ans += 8 * powmod(n, 26);

47         ans += 6 * powmod(n, 38);

48         printf("Case %d: %d\n", ca++, ans % MOD * Invmod(24, MOD) % MOD);

49     }

50     return 0;

51 }
View Code

 


 

HDU 4638 Group 

询问区间最少可以组成多少段,连续的数可以组成一段。

若x+1与x-1已经出现了,则加入x使得段数-1。

若x+1与x-1都没有出现,则加入x使得段数+1。

其他情况段数不变。

 1 #include<cstdio>

 2 #include<cstring>

 3 #include<algorithm>

 4 #define MAXN 100010

 5 using namespace std;

 6 int n, m;

 7 bool vis[MAXN];

 8 int arr[MAXN];

 9 int tree[MAXN];

10 int res[MAXN];

11 int pos[MAXN];

12 struct Ask {

13     int x, y;

14     int idx;

15     friend bool operator<(Ask a, Ask b) {

16         return a.x < b.x;

17     }

18 } ask[MAXN];

19 inline int lowbit(int x) {

20     return x & -x;

21 }

22 void update(int x, int val) {

23     for (; x < MAXN; x += lowbit(x)) {

24         tree[x] += val;

25     }

26 }

27 int sum(int x) {

28     int ans;

29     for (ans = 0; x > 0; x -= lowbit(x)) {

30         ans += tree[x];

31     }

32     return ans;

33 }

34 int main() {

35     int T;

36     int i, j;

37     scanf("%d", &T);

38     while (T--) {

39         scanf("%d%d", &n, &m);

40         for (i = 1; i <= n; i++) {

41             scanf("%d", &arr[i]);

42             pos[arr[i]] = i;

43         }

44         for (i = 0; i < m; i++) {

45             scanf("%d%d", &ask[i].x, &ask[i].y);

46             ask[i].idx = i;

47         }

48         sort(ask, ask + m);

49         memset(tree, 0, sizeof(tree));

50         memset(vis, false, sizeof(vis));

51         for (i = 1; i <= n; i++) {

52             vis[arr[i]] = true;

53             if (vis[arr[i] - 1] && vis[arr[i] + 1]) {

54                 update(i, -1);

55             }

56             if (!vis[arr[i] - 1] && !vis[arr[i] + 1]) {

57                 update(i, 1);

58             }

59         }

60         for (i = 0, j = 1; i < m; i++) {

61             for (; j < ask[i].x; j++) {

62                 if (vis[arr[j] + 1]) {

63                     update(pos[arr[j] + 1], 1);

64                 }

65                 if (vis[arr[j] - 1]) {

66                     update(pos[arr[j] - 1], 1);

67                 }

68                 vis[arr[j]] = false;

69             }

70             res[ask[i].idx] = sum(ask[i].y) - sum(ask[i].x - 1);

71         }

72         for (i = 0; i < m; i++) {

73             printf("%d\n", res[i]);

74         }

75     }

76     return 0;

77 }
View Code

 


 

HDU 4639 Hehe

dp[i]表示以i结尾的方案数。

dp[i]=dp[i-1]。

若替换“hehe”,dp[i]+=dp[i-4]。

 1 #include<cstdio>

 2 #include<cstring>

 3 #define MAXN 100010

 4 #define MOD 10007

 5 int dp[MAXN];

 6 char str[MAXN];

 7 int main() {

 8     int T;

 9     int ca = 1;

10     int len;

11     int i;

12     scanf("%d", &T);

13     while (T--) {

14         scanf(" %s", str + 1);

15         len = strlen(str + 1);

16         dp[0] = 1;

17         for (i = 1; i <= len; i++) {

18             dp[i] = dp[i - 1];

19             if (i > 3 && str[i - 3] == 'h' && str[i - 2] == 'e'

20                     && str[i - 1] == 'h' && str[i] == 'e') {

21                 dp[i] += dp[i - 3];

22             }

23             dp[i] %= MOD;

24         }

25         printf("Case %d: %d\n", ca++, dp[len]);

26     }

27     return 0;

28 }
View Code

 


 

4640 Island and study-sister

dp[i][j]表示访问了的地点压缩成i,最后访问的是j,它的最小花费。

f[i][j]表示i个人,共同访问的地点压缩成j,它的最小花费。

  1 #include<cstdio>

  2 #include<cstring>

  3 #include<vector>

  4 #include<queue>

  5 #define MAXN 17

  6 #define MAXM 3

  7 #define oo 987654321

  8 using namespace std;

  9 int g[MAXN + 1][MAXN + 1];

 10 int dis[MAXN + 1][MAXN + 1];

 11 int dp[1 << MAXN][MAXN];

 12 int f[MAXM + 1][1 << MAXN];

 13 vector<int> island;

 14 void floyd(int n) {

 15     for (int k = 0; k < n; k++) {

 16         for (int i = 0; i < n; i++) {

 17             for (int j = 0; j < n; j++) {

 18                 dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);

 19             }

 20         }

 21     }

 22 }

 23 bool getHelp() {

 24     for (int i = 0; i < (int) island.size(); i++) {

 25         if (dis[1][island[i]] >= oo) {

 26             return false;

 27         }

 28     }

 29     return true;

 30 }

 31 queue<pair<int, int> > q;

 32 int main() {

 33     int T;

 34     int ca = 1;

 35     int n, m, p;

 36     int x, y, val;

 37     int i, j, k;

 38     int vis;

 39     int ans;

 40     pair<int, int> head, tmp;

 41     scanf("%d", &T);

 42     while (T--) {

 43         scanf("%d%d", &n, &m);

 44         memset(g, 0x3f, sizeof(g));

 45         memset(dis, 0x3f, sizeof(dis));

 46         for (i = 0; i < m; i++) {

 47             scanf("%d%d%d", &x, &y, &val);

 48             x--;

 49             y--;

 50             g[x][y] = min(g[x][y], val);

 51             dis[x][y] = dis[y][x] = g[y][x] = g[x][y];

 52         }

 53         island.clear();

 54         scanf("%d", &p);

 55         for (i = 0; i < p; i++) {

 56             scanf("%d", &x);

 57             x--;

 58             island.push_back(x);

 59         }

 60         floyd(n);

 61         if (getHelp()) {

 62             memset(dp, 0x3f, sizeof(dp));

 63             dp[1][0] = 0;

 64             q.push(make_pair(1, 0));

 65             while (!q.empty()) {

 66                 head = q.front();

 67                 q.pop();

 68                 for (i = 0; i < n; i++) {

 69                     tmp.first = head.first | (1 << i);

 70                     tmp.second = i;

 71                     if (dp[tmp.first][tmp.second]

 72                             > dp[head.first][head.second]

 73                                     + g[head.second][tmp.second]) {

 74                         dp[tmp.first][tmp.second] = dp[head.first][head.second]

 75                                 + g[head.second][tmp.second];

 76                         q.push(tmp);

 77                     }

 78                 }

 79             }

 80             memset(f, 0x3f, sizeof(f));

 81             f[1][0] = 0;

 82             for (i = 1; i < (1 << n); i += 2) {

 83                 for (j = 0; j < n; j++) {

 84                     f[1][i] = min(f[1][i], dp[i][j]);

 85                 }

 86             }

 87             for (i = 2; i <= MAXM; i++) {

 88                 for (j = 1; j < (1 << n); j += 2) {

 89                     for (k = j; k >= 0; k = k ? (k - 1) & j : -1) {

 90                         f[i][j] = min(f[i][j],

 91                                 max(f[i - 1][k | 1], f[1][(j ^ k) | 1]));

 92                     }

 93                 }

 94             }

 95             vis = 0;

 96             for (i = 0; i < (int) island.size(); i++) {

 97                 vis |= 1 << island[i];

 98             }

 99             ans = oo;

100             for (i = 0; i < (1 << n); i++) {

101                 if ((i & vis) == vis) {

102                     ans = min(ans, f[3][i]);

103                 }

104             }

105         } else {

106             ans = -1;

107         }

108         printf("Case %d: %d\n", ca++, ans);

109     }

110     return 0;

111 }
View Code

 


 

HDU 4642 Fliping game

若右下角的数为1,则Alice必胜。Alice先把右下角变为0,无论Bob如何操作右下角的数都会变为1。

若右下角的数为0,则Alice必败。Alice会把右下角的数变为1。

 1 #include<cstdio>

 2 int main() {

 3     int T;

 4     int n, m;

 5     int i, j, k;

 6     scanf("%d", &T);

 7     while (T--) {

 8         scanf("%d%d", &n, &m);

 9         for (i = 0; i < n; i++) {

10             for (j = 0; j < m; j++) {

11                 scanf("%d", &k);

12             }

13         }

14         if (k) {

15             puts("Alice");

16         } else {

17             puts("Bob");

18         }

19     }

20     return 0;

21 }
View Code

 

你可能感兴趣的:(test)