2013腾讯编程马拉松初赛(3月20日)

1 第一题 小Q系列故事——屌丝的逆袭

  表示这道题基本没什么算法,学过计算机语言的应该都能搞定吧。

2 第二题 小明系列故事——买年货

  这道题直接用01背包问题就可以解决了,只是除了钱的限制,还有积分的限制和免费的情况,就是这点在调试程序的时候出了点小问题,总是wa。状态可以定义为dp[x][y][z],x表示钱的,y表示积分的,z表示免费的状态,然后其它的和背包问题差不多了,只是维数到了3维。

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 #define max(a,b) a > b ? a : b
 5 int n, v1, v2, k;
 6 typedef struct _thing
 7 {
 8     int a;
 9     int b;
10     int val;
11 }thing_t;
12 
13 int main(void)
14 {
15     thing_t data[101];
16     int ans;
17     int dp[101][101][6];
18     int i,j,y,x, temp;
19     while (scanf("%d%d%d%d", &n, &v1, &v2, &k) != EOF)    
20     {
21         for (i = 1; i <= n; i ++)    
22             scanf("%d%d%d", &data[i].a, &data[i].b, &data[i].val);    
23         memset(dp, -1, sizeof(dp));
24         ans = 0;
25         dp[0][0][0] = 0;
26         for (i = 1; i <= n; i ++)
27         {
28             for (j = v1; j >= 0; j --)
29             {
30                 for (y = v2; y >= 0; y --)
31                 {
32                     for (x = k; x >= 0; x --)
33                     {
34                         temp = -1;
35                         if (j - data[i].a >= 0 && dp[j - data[i].a][y][x] != -1)
36                         {
37                             if( temp < dp[j - data[i].a][y][x] + data[i].val)38                                 temp = dp[j - data[i].a][y][x] + data[i].val;
39                         }
40                         if (y - data[i].b >= 0 && dp[j][y - data[i].b][x] != -1)
41                         {
42                             if( temp < dp[j][y - data[i].b][x] + data[i].val)
43                                 temp = dp[j][y - data[i].b][x] + data[i].val;
44                         }
45                         if (x - 1 >= 0 && dp[j][y][x - 1] != -1)
46                         {
47                             if( temp < dp[j][y][x - 1] + data[i].val)
48                                 temp = dp[j][y][x - 1] + data[i].val;
49                         }
50                         dp[j][y][x] = max(temp, dp[j][y][x]);
51                         if (ans < dp[j][y][x])
52                             ans = dp[j][y][x];
53                     }
54                 }
55             }
56         }
57         printf("%d\n", ans);
58     }
59     return 0;
60 }

3 第三题 吉哥系列故事——临时工计划

  这个题目就直接用dp了,dp[x]表示前x天内获得的最大工资数,状态方程为:

  dp[x] = max{dp[y] + c[y + 1][x]} ,其中c[y + 1][x]表示某份从第y + 1天到第x天的工作的工资,1 <= y <= x - 1 且 c[y + 1][x]不为0。

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 int t;
 5 int m,n;
 6 int data[101][101];
 7 int ans[101];
 8 
 9 int main(void)
10 {
11     int i, j, k, s, e, c;
12     scanf("%d", &t);
13     for (i = 1; i <= t; i ++)
14     {
15         scanf("%d%d", &m, &n);    
16         memset(data, 0 ,sizeof(data));
17         for (j = 1; j <= n; j ++)    
18         {
19             scanf("%d%d%d", &s, &e, &c);    
20             if (data[s][e] < c)
21                 data[s][e] = c;
22         }
23         ans[0] = 0;
24         for (j = 1; j <= m; j ++)
25         {
26             ans[j] = ans[j - 1];
27             for (k = 1; k <= j; k ++)
28                 if (data[k][j] && ans[k - 1] + data[k][j] > ans[j])
29                     ans[j] = ans[k - 1] + data[k][j];
30         }
31         printf("%d\n", ans[m]);
32     }
33     return 0;
34 }

湫湫系列故事——植树节

  思路:根据题目选的3个人互不认识或者都认识则关系相同,从这种关系相同的反面来看就是3个人只有两个认识,最后一个人不认识,所以可以求这种反面情况的个数,对于第i个人,可以选他自己和他的朋友一个即a中情况,剩余一个人选他不认识的人(即非朋友)即n-a-1中情况,所以sum +=a*(n-a-1),sum表示总情况数,由于自己和朋友计算的时候会多算一次,所以最后要sum /= 2才是反面的情况总数。

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     int t, n, b, i, j, all;
 6     double sum;
 7 
 8     scanf("%d", &t);
 9     for (i = 0; i < t; i ++)
10     {
11         scanf("%d", &n);
12         all = n * (n - 1) * (n - 2) / 6;
13         sum = 0.0;
14         for (j = 0; j < n; j ++)
15         {
16             scanf("%d", &b);
17             sum += b * (n - b - 1);
18         }
19         sum /= 2;
20         sum /= all;
21         printf("%.3lf\n", 1 - sum);
22     }
23     return 0;
24 }

威威猫系列故事——篮球梦

  首先算出B队最终的得分sb,再算出要赢B队至少要得的分sum = sb + 1 - a(a为A队当前的得分),然后穷举满足后面得分不小于sum的所有情况。

 1 #include <stdio.h>
 2 
 3 int a, b, t;
 4 __int64 ans;
 5 int sum;
 6 
 7 __int64 f(int start) /*计算阶乘*/
 8 {
 9     __int64 ans = 1;
10     
11     while (start > 1)
12     {
13         ans *= start;
14         start --;
15     }
16     return ans;
17 }
18 
19 int main(void)
20 {
21     int i,j;
22     long long c_w, c_d;
23 
24     while (scanf("%d%d%d", &a, &b, &t) != EOF)    
25     {
26         c_w = t / 15;
27         if (c_w % 2 == 0)
28             c_w = t / 30;
29         else
30             c_w = t / 30 + 1;
31         c_d = t / 30;
32         sum = b + c_d + 1 - a;
33         ans = 0;
34         for (i = 0; i <= c_w; i ++)
35             for (j = 0; j <= c_w - i; j ++)
36                 if (i * 1 + j * 2 + (c_w - i - j) * 3 >= sum)
37                     ans += f(c_w) / (f(i) * f(j) * f(c_w - i - j));
38         printf("%I64d\n", ans);
39     }
40     return 0;
41 }
原文地址:https://www.cnblogs.com/chengxuyuancc/p/3023629.html