2013腾讯编程马拉松初赛第〇场(3月20日) 题解

2013腾讯编程马拉松初赛第〇场(320日) 题解

4500

Q系列故事——屌丝的逆袭

简单模拟

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
const int N = 22;
int a[N][N] , f[N][N] , n , m;
bool inmap(int x,int y) {
    return x>=0 && x < n && y>=0 && y < m;
}
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int main() {
    while(~scanf("%d%d",&n,&m) && n+m) {
        memset(f,0,sizeof(f));
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) scanf("%d",&a[i][j]);
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) {
            for(int k=0;k<4;k++) {
                int ii = i + dir[k][0];
                int jj = j + dir[k][1];
                if(!inmap(ii,jj)) continue;
                if(a[i][j]*a[ii][jj] < 0) f[i][j] += abs(a[ii][jj]);
                else f[i][j] -= abs(a[ii][jj]);
            }
        }
        int fi=0 , fj = 0;
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(f[i][j] > f[fi][fj]) fi = i , fj = j;
        printf("%d %d %d\n",fi+1,fj+1,f[fi][fj]);
    }
    return 0;
}

4501

小明系列故事——买年货

三维的0-1背包

f[i][j][k]表示花费金钱i,优惠券j,免费拿了k件物品的时候的最大价值。f[i][j][k]=max(f[i][j][k],f[i-a][j][k]+c,f[i][j-b][k]+c,f[i][j][k-1]+c),其中a,b,c分别表示单件物品的所需现金,代金券,和价值。

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
int n , v1 , v2 , K;
const int N = 110;
int f[N][N][6];
int ans;
void chk(int a,int b,int c) {
    for(int i=v1;i>=0;i--)
    for(int j=v2;j>=0;j--)
    for(int k=K;k>=0;k--) {
        int tmp = 0;
        if(i >= a) checkmax(tmp , f[i-a][j][k] + c);
        if(j >= b) checkmax(tmp , f[i][j-b][k] + c);
        if(k > 0) checkmax(tmp , f[i][j][k-1] + c);
        checkmax(f[i][j][k] , tmp);
    }
}
int a[N] , b[N] , c[N];
int main() {
    while(~scanf("%d%d%d%d",&n,&v1,&v2,&K)) {
        for(int i=0;i<n;i++) scanf("%d%d%d",a+i,b+i,c+i);
        memset(f ,0 ,sizeof(f));
        ans = 0;
        for(int i=0;i<n;i++) chk(a[i] , b[i] , c[i]);
        //printf("%d\n" , ans);
        printf("%d\n",f[v1][v2][K]);
    }
    return 0;
}

 

下面的代码不知为什么错了:╮(╯▽╰)╭

4501错误代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
int n , v1 , v2 , K;
const int N = 110;
int f[N][N][6];
int ans;
void chk(int a,int b,int c) {
    for(int i=v1;i>=0;i--)
    for(int j=v2;j>=0;j--)
    for(int k=K;k>=0;k--) {
        if(i >= a) checkmax(f[i][j][k] , f[i-a][j][k] + c);
        if(j >= b) checkmax(f[i][j][k] , f[i][j-b][k] + c);
        if(k > 0) checkmax(f[i][j][k] , f[i][j][k-1] + c);
        checkmax(ans , f[i][j][k]);
    }
}
int a[N] , b[N] , c[N];
int main() {
    while(~scanf("%d%d%d%d",&n,&v1,&v2,&K)) {
        for(int i=0;i<n;i++) scanf("%d%d%d",a+i,b+i,c+i);
        memset(f ,0 ,sizeof(f));
        ans = 0;
        for(int i=0;i<n;i++) chk(a[i] , b[i] , c[i]);
        printf("%d\n" , ans);
        //printf("check : %d\n",f[v1][v2][K]);
    }
    return 0;
}

 

4502

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

贪心+动态规划:把工作按结束时间从早到晚排一个序,然后进行0-1背包即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
const int N = 1010;
int f[111];
struct node {
    int s , t , c;
}a[N];
bool cmp(node a , node b) {
    if(a.t != b.t) return a.t < b.t;
    return a.s < b.s;
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int m , n;
        scanf("%d%d",&m,&n);
        for(int i=0;i<n;i++) {
            scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].c);
        }
        for(int i=0;i<=m;i++) f[i] = 0;
        sort(a , a+n , cmp);
        for(int i=0;i<n;i++) {
            int tmp = 0;
            for(int j=0;j<a[i].s;j++) checkmax(tmp,f[j]);
            checkmax(f[a[i].t] , a[i].c+tmp);
        }
        int ans = 0;
        for(int i=1;i<=m;i++) checkmax(ans , f[i]);
        printf("%d\n" , ans);
    }
    return 0;
}

 

4503

湫湫系列故事——植树节

 总的情况数是C(n,3)=n*(n-1)*(n-2)/6;找出所有不符合的情况(即选出的三个人之中两个人是好友关系,另一个人跟着两个人不是好友关系)=∑a[i]*(n-a[i]-1) / 2;

两书相减就是所有符合条件的情况数,属于总情况数就是概率。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
int n , a[1010] , T;
int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        int a1 = 0;
        for(int i=0;i<n;i++) {
            scanf("%d",&a[i]);
            a1 += a[i] * (n - a[i] - 1);
        }
        a1 /= 2;
        int a2 = n * (n-1) * (n-2) / 6;
        printf("%.3lf\n" , 1.0 - (double)a1/(double)a2);
    }
    return 0;
}

4504

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

动态规划,先预处理,f[i][j]表示第i次进攻后我方得分j的最多方案数

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
ll f[100][100];
int n , a , b;
void init() {
    f[1][1] = f[1][2] = f[1][3] = 1;
    for(int i=1;i<=20;i++)
    for(int j=1;j<=60;j++) {
        if(j > 1) f[i][j] += f[i-1][j-1];
        if(j > 2) f[i][j] += f[i-1][j-2];
        if(j > 3) f[i][j] += f[i-1][j-3];
    }
}
int main() {
    init();
    while(~scanf("%d%d%d",&a,&b,&n)) {
        n /= 15;
        int n1 = (n+1)/2 , n2 = n - n1;
        if(n1 == 0) {
            puts(a>b?"1":"0");
            continue;
        }
        b += n2;
        int tmp = b - a + 1;
        checkmax(tmp , 0);
        ll ans = 0;
        for(int i=tmp;i<=n1*3;i++)
            ans += f[n1][i];
        cout << ans << endl;
    }
    return 0;
}

 

 

转载于:https://www.cnblogs.com/aiiYuu/archive/2013/04/01/2993752.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值