Codeforces Round #336 div2

Codeforces Round #336 div2
通过数:3(1题未来得及交)
Standing: 418
题目链接:
http://codeforces.com/contest/608
A:
到一个楼层的时候,如果有人,则更新ans = Max(ans, 此人等待时间)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 1000 + 5;
int n, s;
struct D
{
    int f, t;
}d[MAXN];
bool cmp(D a, D b){return a.f < b.f;}
int main()
{
    while(scanf("%d%d", &n, &s) != EOF){
        for(int i = 1 ; i <= n ; i++)   scanf("%d%d", &d[i].f, &d[i].t);
        int pre = s;
        int ans = 0;
        sort(d + 1 , d + 1 + n, cmp);
        for(int i = n ; i >= 1 ; i--){
            ans += pre - d[i].f;
            if(ans < d[i].t)    ans = d[i].t;
            pre = d[i].f;
        }
        printf("%d\n", ans);
    }
    return 0;
}

B:
额,用了一种比较麻烦的写法。对b串统计一下每个位能在a中哪些位进行了使用。因为是一个连续区间段,所以用前缀和的方法处理就好。
更好的一种写法是统计a中每个位在b中哪些位置进行了使用,可以减少一个数组,也相对好处理一些。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std;
const int MAXN = 200000 + 5;
char a[MAXN], b[MAXN];
long long a1[2][MAXN];
int main()
{
    while(scanf("%s %s", a, b) != EOF){
        int n = strlen(a);
        int m = strlen(b);
        a1[0][0] = a[0] == '0' ? 1 : 0;
        a1[1][0] = a[0] == '0' ? 0 : 1;
        for(int i = 1 ; i < n ; i++){
            a1[0][i] = a1[0][i - 1], a1[1][i] = a1[1][i - 1];
            if(a[i] == '0') a1[0][i]++;
            else    a1[1][i]++;
        }
        long long ans = 0;
        for(int j = 0 ; j < m ; j++){
            int mark = b[j] == '0' ? 1 : 0;
            int le = max(n - m + j, 0);
            int re = min(n - 1, j);
            ans += a1[mark][re];
            if(le != 0) ans -= a1[mark][le - 1];
        }
        printf("%I64d\n", ans);
    }
    return 0;
}

C:
因为加在最后的点攻击范围不确定,所以答案就相当于枚举每个点作为最后一个点的时候,能存活下来的点。
现场采用了一种二分的写法。假设当前点存活,二分在前面查找一个最近且不会被攻击到的点。
然而又有一种更优的写法。因为位置<=1e5,所以直接每个位置存信息就可以。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int MAXN = 100000 + 5;
struct D
{
    int u, v;
}d[MAXN], e[MAXN];
bool cmp(D a, D b){return a.u < b.u;}
int dp[MAXN];
int main()
{
    int n;
    while(scanf("%d", &n) != EOF){
        d[0].u = 0;
        for(int i = 1 ; i <= n ; i++)   scanf("%d%d", &d[i].u, &d[i].v);
        sort(d + 1, d + n + 1, cmp);
        dp[0] = 0;
        int ans = n;
        for(int i = 1 ; i <= n ; i++){
            dp[i] = 1;
            if(i == 1)  continue;
            int val = d[i].u - d[i].v;
            val = max(val, 0);
            int le = 0, re = i - 1;
            while(le < re - 1){
                int mid = (le + re) >> 1;
                if(d[mid].u < val) le = mid;
                else re = mid;
            }
            int mark;
            if(d[re].u < val)  mark = re;
            else mark = le;
            dp[i] += dp[mark];
//            printf("ans[%d] = %d, mark = %d\n", i, dp[i], mark);
        }
        for(int i = 1 ; i <= n ; i++)   ans = min(ans, n - dp[i]);
        printf("%d\n", ans);
    }
    return 0;
}

D:
区间DP
dp[i][i] = 1,
Dp[i][i+1] = a[i] == a[i+1] ? 1 : 2,
Dp[i][j] = min{dp[i][k] + dp[k + 1][j]}
如果a[i] == a[j],dp[i][j] = min{dp[i][j], dp[i+1][j-1]}

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define inf (1000000007)
const int MAXN = 500 + 5;
int dp[MAXN][MAXN];
int a[MAXN];
int main()
{
    int n;
    while(scanf("%d", &n) != EOF){
        for(int i = 1 ; i <= n ; i++)   for(int j = 1 ; j <= n ; j++)   dp[i][j] = inf;
        for(int i = 1 ; i <= n ; i++)   scanf("%d", &a[i]), dp[i][i] = 1;
        for(int i = 1 ; i < n ; i++){
            if(a[i] == a[i + 1])    dp[i][i + 1] = 1;
            else    dp[i][i + 1] = 2;
        }
        for(int i = 2 ; i <= n ; i++){
            for(int j = 1 ; j + i <= n ; j++){
                if(a[j] == a[j + i])
                    dp[j][j + i] = dp[j + 1][j + i - 1];
//                else{

                    dp[j][j + i] = min(dp[j][j + i], dp[j + 1][j + i] + 1);
                    dp[j][j + i] = min(dp[j][j + i], dp[j][j + i - 1] + 1);
                    for(int k = j + 1 ; k < j + i ; k++){
                        int temp = dp[j][k] + dp[k + 1][j + i];
                        dp[j][j + i] = min(dp[j][j + i], temp);
//                    }
                }
            }
        }
//        for(int i = 1 ; i <= n ; i++){
//            for(int j = 1 ; j <= n ; j++)   printf("%d ", dp[i][j]);
//            printf("\n");
//        }
        printf("%d\n", dp[1][n]);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值