5.7 ~ 5.12 刷题列表

USACO Raucous Rockers  搜索水题

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;

int n, m, t;

int ans;

int a[25];

int rest[25];

int pos;

void dfs(int now, int sum)
{
    if (now == n + 1){
        ans = max(ans, sum);
        return ;
    }
    
    if (sum + n + 1 - now <= ans) return ;//剪枝
    
    if (rest[pos] >= a[now]){  //xuan ze zhe ge
        rest[pos] -= a[now];
        dfs(now + 1, sum + 1);
        rest[pos] += a[now];
    }
    
    if (pos < m and rest[pos+1] >= a[now])  { // xuan ze xia yi ge
        pos++;
        rest[pos] -= a[now];
        dfs(now + 1, sum + 1);
        rest[pos] += a[now];
        pos--;
    }
    
    dfs(now + 1, sum); //bu xuan ze
    
}

int main()
{
    cin >> n >> t >> m;
    for (register int i = 1 ; i <= n ; i ++) scanf("%d", &a[i]);
    
    for (register int i = 1 ; i <= m ; i ++) rest[i] = t;
    
    dfs(1, 0);
    
    cout << ans << endl;
    return 0;
}
zZhBr

 Noip2011 聪明的质检员 二分答案,前缀和

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define int long long

int n, m, s;
int w[200010], v[200010];
int sw[200010], sv[200010];

int li[200010], ri[200010];

int l, r, mid;

int res, sum;

int ans = 0x7f7f7f7f7f7f7f7f7f;

bool check(int x)
{
    res = 0, sum = 0;
    int aa = 0;
    
    for (int i = 1 ; i <= n ; i ++){
        if(w[i] < x) sv[i] = sv[i-1], sw[i] = sw[i-1];
        else {
            sv[i] = sv[i-1] + v[i];
            sw[i] = sw[i-1] + 1;
        }
    }
    
    for (int i = 1 ; i <= m ; i ++){
        res += (sw[ri[i]] - sw[li[i]-1]) * (sv[ri[i]] - sv[li[i]-1]);
    }
    
//    printf("mid = %d, res = %d
", x, res);
    sum = abs(res - s);
    if(res > s) return 1;
    return 0;
}

signed main()
{
    cin >> n >> m >> s;
    
    for (int i = 1 ; i <= n ; i ++){
        scanf("%lld%lld", &w[i], &v[i]);
        sv[i] = sv[i-1] + v[i];
        r = max(r, w[i]);
    }
    
    for (int i = 1 ; i <= m ; i ++){
        scanf("%lld%lld", &li[i], &ri[i]);
    }
    
    while(l <= r){
        mid = l + r >> 1;
        
        bool f = check(mid);
        
        ans = min(ans, sum);
        
        if(f){
            l = mid + 1;
        }
        else r = mid - 1;
    }
    
    cout << ans << endl;
    return 0;
}
zZhBr

 HAOI2010音量调节 DP水题(我不会说我因数组开小WA了n次

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

int n, m, s;
int a[52];
bool dp[52][1010];//第i次, 音量为j是否可行 

int main()
{
    cin >> n >> m >> s;
    
    for (register int i = 1 ; i <= n ; i ++){
        scanf("%d", &a[i]);
    }
    
    dp[0][m] = 1;
    
    for (register int i = 1 ; i <= n ; i ++){
        for (register int j = 0 ; j <= s ; j ++){
            if (dp[i-1][j]){
                if (j + a[i] <= s) dp[i][j+a[i]] = 1;
                if (j - a[i] >= 0) dp[i][j-a[i]] = 1;
            }
        }
    }
    
    for (register int i = s ; i >= 0 ; i --){
        if(dp[n][i]) {
            cout << i << endl;
            return 0;
        }
    }
    puts("-1");
    return 0;
    
}
zZhBr

 USACO 蹄子剪刀布 DP水题

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define regi register

int n, m;

int a[100010];

int dp[100010][51][4];

inline int win(int x, int y)
{
    if (x == 1 and y == 2) return 1;
    if (x == 2 and y == 3) return 1;
    if (x == 3 and y == 1) return 1;
    return 0;
}

inline int Large(int x, int y, int z)
{
    if (x > y) return x > z ? x : z;
    else return y > z ? y : z;
}

int ans1, ans2, ans3;

int main()
{    
    cin >> n >> m;
    
    for (regi int i = 1 ; i <= n ; i++){
        char c;
        cin >> c;
        if (c == 'P') a[i] = 1;
        else if (c == 'H') a[i] = 2;
        else a[i] = 3;
    }
    
    for (regi int i = 1 ; i <= n ; i ++){
        dp[i][0][1] = dp[i-1][0][1] + win(1, a[i]);
        dp[i][0][2] = dp[i-1][0][2] + win(2, a[i]);
        dp[i][0][3] = dp[i-1][0][3] + win(3, a[i]);
    }
    
    for (regi int i = 1 ; i <= n ; i ++){
        for (regi int j = 1 ; j <= m ; j ++){
            dp[i][j][1] = Large(dp[i-1][j][1], dp[i-1][j-1][2], dp[i-1][j-1][3]) + win(1, a[i]);
            dp[i][j][2] = Large(dp[i-1][j][2], dp[i-1][j-1][1], dp[i-1][j-1][3]) + win(2, a[i]);
            dp[i][j][3] = Large(dp[i-1][j][3], dp[i-1][j-1][1], dp[i-1][j-1][2]) + win(3, a[i]);
        }
    }
    
    
    cout << Large(dp[n][m][1], dp[n][m][2], dp[n][m][3]) << endl;;
    return 0;
    
}
zZhBr

 USACO 环绕岛屿 直接暴力 挺好的题,我写了题解 ,戳这里

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define regi register 

int n;

int fa[505];

inline int Find(int x)
{
    return x == fa[x] ? x : fa[x] = Find(fa[x]);
}

int dis[505][505];

int cnt;

int ans = 0x7f7f7f7f;

int pos[505];

int main()
{
    cin >> n;
    
    for (regi int i = 1 ; i <= n ; i ++) fa[i] = i;
    
    memset(dis, 0x7f, sizeof dis);
    
    for (regi int i = 1 ; i <= n ; i ++){
        int x, y;
        scanf("%d%d", &x, &y);
        int fx = Find(x), fy = Find(y);
        if (fx != fy) fa[fx] = fy;
    }
    
    for (regi int i = 1 ; i <= n ; i ++){
        if (fa[i] == i) pos[++cnt] = i;
    }
    
    for (regi int i = 1 ; i <= n ; i ++){
        int fi = Find(i);
        for (regi int j = 1 ; j <= n ; j ++){
            int fj = Find(j);
            int d;
            scanf("%d", &d);
            dis[fi][fj] = min(dis[fi][fj], d);            
        }
    }
    
    for (regi int i = 1 ; i <= cnt ; i ++){
        int sum = 0;
        for (regi int j = 1 ; j <= cnt ; j ++){
            if (i == j) continue;
            sum += dis[pos[i]][pos[j]];
        }
        ans = min(ans, sum);
    }
    
//    printf("dis==%d
", dis[4][10]);
    
    cout << ans * 2 << endl;
    
    return 0;
}
zZhBr

 USACO吃巧克力 二分水题, 坑点 : 没吃完的放到最后一天吃,还有记得开long long, 坑了我5次

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define regi register 
#define int long long

int n, d;

int a[50005];
int tim[50005];
int b[50005];

int l = 1, r, mid;

int ans;

bool check(int x)
{
    int now = 0, j = 1;
    
    for (regi int i = 1 ; i <= d ; i ++){
        now /= 2;
        while (now < x and j <= n){
            now += a[j];
            b[j] = i;
            j ++;
        }
        if (now < x) return 1;
    }
    
    for (regi int i = 1 ; i <= n ; i ++) tim[i] = d;
    for (regi int i = 1 ; i < j ; i ++) tim[i] = b[i];
    
    return 0;
}

signed main()
{
    cin >> n >> d;
    
    for (regi int i = 1 ; i <= n ; i ++){
        scanf("%lld", &a[i]);
        r += a[i];
    }
    
    while (l <= r){
        mid = l + r >> 1;
        bool f = check(mid);
        if (f){
            r = mid - 1;
        }
        else{
            l = mid + 1;
            ans = mid;
        }
    }    
    
    cout << ans << endl;
    
    for (regi int i = 1 ; i <= n ; i ++){
        printf("%lld
", tim[i]);
    }
    
    return 0;
}
zZhBr
原文地址:https://www.cnblogs.com/BriMon/p/9005247.html