1. 程式人生 > >2013騰訊編程馬拉松初賽第0,1場

2013騰訊編程馬拉松初賽第0,1場

-- mat cnblogs math pen bool hid pla !=

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\n",sum); if(i==1&&j==1) mx=sum; if(sum>mx) { a=i; b=j; mx=sum; } } } printf("%d %d %d\n",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\n",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\n",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\n",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\n",i,dp[i][ti]);
        }
        printf("%I64d\n",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\n",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\n",(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\n",(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\n",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\n",sum);
    }
    return 0;
}
View Code

2013騰訊編程馬拉松初賽第0,1場