2013腾讯编程马拉松初赛第〇场

http://acm.hdu.edu.cn/listproblem.php?vol=36

1:小Q系列故事——屌丝的逆袭

思路:和省赛的那个题目类似,只要模拟一下就好...

View Code
#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll long long

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);

#define inf 0x7f7f7f7f



#define M 150

#define N 22

using namespace std;





int mat[N][N];

int ans[N][N];

int n,m;

int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};



int Abs(int x)

{

    if (x >= 0) return x;

    else return (-x);

}

int main()

{

    int i,j,k;

    while (~scanf("%d%d",&n,&m))

    {

        if (!n && !m) break;

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

        {

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

            {

                scanf("%d",&mat[i][j]);

            }

        }

        CL(ans,0);





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

        {

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

            {

                for (k = 0; k < 4; ++k)

                {

                    int ti = i + dir[k][0];

                    int tj = j + dir[k][1];

                    if (ti >= 0 && ti < n && tj >= 0 && tj < m)

                    {

                        if (mat[i][j]*mat[ti][tj] < 0)

                        ans[i][j] += Abs(mat[ti][tj]);

                        else ans[i][j] -= Abs(mat[ti][tj]);

                    }

                }

            }

        }

        int res = -inf;

        int row = 0, col = 0;

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

        {

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

            {

                    if (ans[i][j] > res)

                    {

                        res = ans[i][j];

                        row = i;

                        col = j;

                    }

                    else if (ans[i][j] == res && ((row > i) || (row == i && col > j)))

                    {

                        res = ans[i][j];

                        row = i;

                        col = j;

                    }

    //               printf("%d ",ans[i][j]);

            }

//           printf("\n");

        }

//        if (res == -inf) res = 0;

        printf("%d %d %d\n",row + 1,col + 1,res);

    }

    return 0;

}

 

2:小明系列故事——买年货

思路:DP ,才开始开了个三维的DP怎么调数据都不出来,后来一看不对。这样会出现重复选的可能。后来开成了四维,没有用滚动数组优化就可以过,不过时间还是很紧的。

dp[no][i][j][k] = max(dp[no][i][j][k],dp[no - 1][i - a][j][k] + val,dp[no - 1][i][j - b][k] + val,dp[no - 1][i][j][k - 1] + val,dp[no - 1][i][j][k]);

前几个还好想,就是在dp[no - 1][i][j][k]没处理好,就是对于这件物品,我可能不买。 no表示第几件物品,i表示金钱数,j表示积分,k表示可以免费领取的商品数。

View Code
//#pragma comment(linker,"/STACK:327680000,327680000")

#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll __int64

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define M 307

#define N 4100007

using namespace std;



struct node

{

    int a,b,val;

}nd[107];



int dp[107][107][107][6];



int n,v1,v2,k;



int DP(int no,int vi,int vj,int ki)

{



    if (no < 0 || vi < 0 || vj < 0 || ki < 0) return -1;



    if (dp[no][vi][vj][ki]) return dp[no][vi][vj][ki];

    int tmp;



    tmp = DP(no - 1,vi - nd[no].a,vj,ki);

    if (tmp != -1)

    {

        tmp += nd[no].val;

        dp[no][vi][vj][ki] = max(dp[no][vi][vj][ki],tmp);

    }



    tmp = DP(no - 1,vi,vj - nd[no].b,ki);

    if (tmp != -1)

    {

        tmp += nd[no].val;

        dp[no][vi][vj][ki] = max(dp[no][vi][vj][ki],tmp);

    }



    tmp = DP(no - 1,vi,vj,ki - 1);

    if (tmp != -1)

    {

        tmp += nd[no].val;

        dp[no][vi][vj][ki] = max(dp[no][vi][vj][ki],tmp);

    }



    tmp = DP(no - 1,vi,vj,ki);

    if (tmp != -1)

    dp[no][vi][vj][ki] = max(dp[no][vi][vj][ki],tmp);





    return dp[no][vi][vj][ki];

}

int main()

{

//    Read();

    int i;

    while (~scanf("%d%d%d%d",&n,&v1,&v2,&k))

    {

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

        {

            scanf("%d%d%d",&nd[i].a,&nd[i].b,&nd[i].val);

        }

        CL(dp,0);

        printf("%d\n",DP(n,v1,v2,k));

    }

    return 0;

}

 

优化到三维后相当于多维的01背包:

View Code
//#pragma comment(linker,"/STACK:327680000,327680000")

#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll __int64

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define M 307

#define N 4100007

using namespace std;



struct node

{

    int a,b,val;

}nd[107];



int dp[107][107][6];

int n,v1,v2,k;



int main()

{

//    Read();

    int i,j,ki,p;

    while (~scanf("%d%d%d%d",&n,&v1,&v2,&k))

    {

        CL(dp,0);

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

        {

            scanf("%d%d%d",&nd[i].a,&nd[i].b,&nd[i].val);

        }





        for (p = 1; p <= n; ++p)

        {

            for (i = v1; i >= 0; --i)

            {

                for (j = v2; j >= 0; --j)

                {

                    for (ki = k; ki >= 0; --ki)

                    {



                        int tmp = 0;

                        if (i - nd[p].a >= 0)

                        tmp = max(tmp,dp[i - nd[p].a][j][ki] + nd[p].val);



                        if (j - nd[p].b >= 0)

                        tmp = max(tmp,dp[i][j - nd[p].b][ki] + nd[p].val);



                        if (ki - 1 >= 0)

                        tmp = max(tmp,dp[i][j][ki - 1] + nd[p].val);



                        dp[i][j][ki] = max(dp[i][j][ki],tmp);

                    }

                }

            }

        }

        int ans = 0;

        for (i = 0; i <= v1; ++i)

        {

            for (j = 0; j <= v2; ++j)

            {

                for (ki = 0; ki <= k; ++ki)

                {

//                    printf("%d\n",dp[i][j][ki]);

                    ans = max(ans,dp[i][j][ki]);

                }

            }

        }

        printf("%d\n",ans);

    }

    return 0;

}

 

 

3:吉哥系列故事——临时工计划

思路:DP ,按时间排序之后DP即可,dp[i]表示到第i个工作时,可获得最高的工资.dp[i] += max(dp[k])  k < i

View Code
#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll long long

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);

#define inf 0x7f7f7f7f



#define M 107

#define N 1007

using namespace std;



struct node

{

    int s,e;

    int val;

}nd[N];

int m,n;

int dp[N];



int cmp(node a,node b)

{

    if (a.s != b.s) return a.s < b.s;

    else return a.e < b.e;

}

int main()

{

//    Read();

    int i,j;

    int T;

    int s,e,val;

    scanf("%d",&T);

    while (T--)

    {

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

        int tn = 0;

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

        {

            scanf("%d%d%d",&s,&e,&val);

            if (e >= 1 && e <= m && s >= 1 && s <= m)

            {

                nd[tn].s = s;

                nd[tn].e = e;

                nd[tn++].val = val;

            }

        }

        sort(nd,nd + tn,cmp);

//        for (i = 0; i < tn; ++i)

//        {

//            printf(">>%d %d %d\n",nd[i].s,nd[i].e,nd[i].val);

//        }

        CL(dp,0);

        for (i = 0; i < tn; ++i)

        {

            dp[i] = nd[i].val;

            int tmp = 0;

            for (j = 0; j < i; ++j)

            {

                if (nd[j].e < nd[i].s)

                {

                   tmp = max(tmp,dp[j]);

                }

            }

            dp[i] += tmp;

        }

        int ans = 0;

        for (i = 0; i < tn; ++i)

        {

            ans = max(ans,dp[i]);

        }

        printf("%d\n",ans);

    }

    return 0;

}

 

4:湫湫系列故事——植树节

 思路:直接考虑可能会比较麻烦一点,我们考虑它的反面,只要我们选的其余两个人一个是他朋友,一个不是他朋友就满足了它的对立面,则一共有C(n,3)中组和,每一个i,存在对立面的可能数为a[i]*(an - 1 - a[i])中间会出现计算两次,顾要除以2;

View Code
#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define ll __int64

#define inf 0x7f7f7f7f

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)



#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define N 1007

#define M 1007



const int mod = 1000000007;

using namespace std;

int a[N];



int main()

{

    int i,j;

    int T,n;

    scanf("%d",&T);

    while (T--)

    {

        scanf("%d",&n);

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

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



        int ans = 0;

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

        {

            ans += (a[i]*(n - a[i] - 1));

        }

        double div = n*(n - 1)*(n - 2)/6;

        printf("%.3lf\n",1 - (1.0*ans)/(2*div));

    }

}

 

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

思路:算出A要进攻多少场(m)之后,然后枚举得分分别为1,2,3的场数,就相当于吧这几场往m里面放,那么可能输为C(m,i)*C(m - i,j)*C(m - i - j,k);

View Code
#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define ll __int64

#define inf 0x7f7f7f7f

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)



#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define N 1007

#define M 1007



const int mod = 1000000007;

using namespace std;

int a[N];



int main()

{

    int i,j;

    int T,n;

    scanf("%d",&T);

    while (T--)

    {

        scanf("%d",&n);

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

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



        int ans = 0;

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

        {

            ans += (a[i]*(n - a[i] - 1));

        }

        double div = n*(n - 1)*(n - 2)/6;

        printf("%.3lf\n",1 - (1.0*ans)/(2*div));

    }

}

 

 

你可能感兴趣的:(编程)