2013腾讯编程马拉松初赛第0,1场

HDU4500

直接模拟

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  55
#define ll __int64

int z[MAXN][MAXN];
int s1[4]={1,0,-1,0};
int s2[4]={0,1,0,-1};

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==m&&m==0)
            break;
        memset(z,0,sizeof(z));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
                scanf("%d",&z[i][j]);
        }
        int a,b,mx;
        a=b=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                int sum=0;
                for(int k=0;k<4;k++)
                {
                    int x,y;
                    x=i+s1[k];
                    y=j+s2[k];
                    if(z[i][j]>0)
                    {
                        sum=sum-z[x][y];
                    }
                    else
                    {
                        sum=sum+z[x][y];
                    }
                }
               // printf("%d
",sum);
                if(i==1&&j==1)
                    mx=sum;

                if(sum>mx)
                {
                    a=i;
                    b=j;
                    mx=sum;
                }
            }
        }
        printf("%d %d %d
",a,b,mx);
    }
    return 0;
}
View Code

HDU4501

0 1背包

dp[i][j][k]  代表 用掉 i 次 免费  钱为 j 积分为k 能得到的最大价值

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  110
#define ll __int64

int dp[6][MAXN][MAXN];

struct node
{
    int v1,v2,w;
}z[MAXN];

int main()
{
    int n,v1,v2,k;
    while(scanf("%d%d%d%d",&n,&v1,&v2,&k)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            scanf("%d%d%d",&z[i].v1,&z[i].v2,&z[i].w);
        for(int i=1;i<=n;i++)
        {
            for(int j=v1;j>=0;j--)
            {
                for(int kk=v2;kk>=0;kk--)
                {
                    for(int jj=k;jj>=0;jj--)
                    {
                        int now=0;
                        if(jj>0)
                            now=max(now,dp[jj-1][j][kk]+z[i].w);
                        if(kk>=z[i].v2)
                            now=max(now,dp[jj][j][kk-z[i].v2]+z[i].w);
                        if(j>=z[i].v1)
                            now=max(now,dp[jj][j-z[i].v1][kk]+z[i].w);
                        dp[jj][j][kk]=max(dp[jj][j][kk],now);
                    }
                }
            }
        }
        printf("%d
",dp[k][v1][v2]);
    }
    return 0;
}
View Code

HDU4502

区间DP

dp[i][j]  代表i ~ j 天能得到的最大工资

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  1010
#define ll __int64

int dp[110][110];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&m,&n);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            int a,b,w;
            scanf("%d%d%d",&a,&b,&w);
            dp[a][b]=max(dp[a][b],w);
        }
        for(int l=1;l<=m;l++)
        {
            for(int j=1;j<=m;j++)
            {
                int en=j+l-1;
                for(int k=j;k<en;k++)
                    dp[j][en]=max(dp[j][en],dp[j][k]+dp[k+1][en]);
            }
        }
        printf("%d
",dp[1][m]);
    }
    return 0;
}
View Code

HDU4503

考虑反面  第 i个人 调一个他的朋友 一个不是朋友

a*(n-a-1)    求和除2  就是不满足情况的 然后总的C(n,3)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  1010
#define ll __int64

int dp[110][110];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int num=0;
        for(int i=1;i<=n;i++)
        {
            int a;
            scanf("%d",&a);
            num=num+a*(n-a-1);
        }
        num=num/2;
        int sum=n*(n-1)*(n-2)/6;
        printf("%.3lf
",1.0*(sum-num)/sum);
    }
    return 0;
}
View Code

HDU4504

dp[i][j]  到第 j 次一共拿到i分

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  1010
#define ll __int64

ll dp[1100][40];


int main()
{
    int  n,m,t;
    while(scanf("%d%d%d",&n,&m,&t)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        int a=t/15;
        int b=a/2;
        m=m+b;
        int ti;
        if(a%2==0)
            ti=b;
        else
            ti=b+1;
        dp[n][0]=1;
        for(int i=1;i<=ti;i++)
        {
            for(int j=n+i;j<=n+i*3;j++)
            {
                if(j-1>=0)
                dp[j][i]+=dp[j-1][i-1];
                if(j-2>=0)
                dp[j][i]+=dp[j-2][i-1];
                if(j-3>=0)
                dp[j][i]+=dp[j-3][i-1];
            }
        }
        ll sum=0;
        for(int i=m+1;i<=n+ti*3;i++)
        {
             sum=sum+dp[i][ti];
            // printf("%d %d
",i,dp[i][ti]);
        }
        printf("%I64d
",sum);
    }
    return 0;
}
View Code

HDU4505

可以一起下电梯

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  110
#define ll __int64

int z[MAXN];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(z,0,sizeof(z));
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int a;
            scanf("%d",&a);
            z[a]++;
        }
        int ans=0;
        for(int i=100;i>=1;i--)
        {
            if(z[i])
            {
                ans=ans+10*i;
                break;
            }
        }
        for(int i=1;i<=100;i++)
        {
            if(z[i])
            {
                ans=ans+5+z[i];
            }
        }
        printf("%d
",ans);

    }
    return 0;
}
View Code

HDU4506

找一下规律 就是一次向后面移一格 然后 乘以k  循环节 n  

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  10010
#define ll __int64

ll Quick(ll a,ll b,ll c)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
            ans=(ans*a)%c;
        b>>=1;
        a=(a*a)%c;
    }
    return ans;
}
ll z[MAXN];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll n,k,t;
        scanf("%I64d%I64d%I64d",&n,&t,&k);
        ll a=Quick(k,t,inf);
        ll b=t%n;
        for(int i=0;i<n;i++)
            scanf("%I64d",&z[i]);

        if(b==n-1)
        {
            for(int i=1;i<=n-1;i++)
                printf("%I64d ",(z[i]*a)%inf);
            printf("%I64d
",(z[0]*a)%inf);
        }
        else
        {
            for(int i=n-b;i<n;i++)
                printf("%I64d ",(z[i]*a)%inf);
            for(int i=0;i<n-b-1;i++)
                printf("%I64d ",(z[i]*a)%inf);
            printf("%I64d
",(z[n-b-1]*a)%inf);
        }

    }
    return 0;
}
View Code

7  数位DP  不过好像不会

HDU4508

完全背包?

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  110
#define ll __int64

struct node
{
    int v,co;
}z[MAXN];
int dp[100010];

int main()
{
    int  n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            scanf("%d%d",&z[i].v,&z[i].co);
        int m;
        scanf("%d",&m);
        for(int i=1;i<=n;i++)
        {
            for(int j=z[i].co;j<=m;j++)
            {
                dp[j]=max(dp[j],dp[j-z[i].co]+z[i].v);
            }
        }
        printf("%d
",dp[m]);
    }
    return 0;
}
View Code

HDU4509

排序 区间的交   线段树麻烦了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  500010
#define ll __int64

struct node
{
    int st,en;
}z[MAXN];
bool cmp(node a,node b)
{
    if(a.st==b.st)
        return a.en<b.en;
    return a.st<b.st;
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            int a,b,c,d;
            scanf("%d:%d %d:%d",&a,&b,&c,&d);
            z[i].st=a*60+b;
            z[i].en=c*60+d;
        }
        sort(z+1,z+n+1,cmp);
        int st,en;
        st=en=0;
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            if(z[i].st>en)
            {
                sum=sum+z[i].st-en;
                st=z[i].st;
                en=z[i].en;
            }
            else if(z[i].st<=en)
            {
                en=max(en,z[i].en);
            }
        }
        if(en<1440)
            sum=sum+1440-en;
        printf("%d
",sum);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/cherryMJY/p/7106831.html