• 寒假训练5解题报告


    1.HDU 1114 Piggy Bank

    一道简单的背包问题

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    #define ll long long
    const int N = 10005;
    const int INF = 0x3f3f3f3f;
    int dp[N];
    
    int main()
    {
       // freopen("a.in" , "r" , stdin);
        int T;
        scanf("%d" , &T);
        while(T--)
        {
            int E , F;
            scanf("%d%d" , &E , &F);
            int M = F-E;
            int n,v,w;
            scanf("%d" , &n);
            memset(dp , 0x3f , sizeof(dp));
            dp[0]=0;
            for(int i=0 ; i<n ; i++){
                scanf("%d%d" , &v , &w);
                for(int j=w ; j<=M ; j++){
                    dp[j] = min(dp[j] , dp[j-w]+v);
                }
            }
            if(dp[M]<INF) printf("The minimum amount of money in the piggy-bank is %d.
    " , dp[M]);
            else puts("This is impossible.");
        }
        return 0;
    }
    View Code

    2.CodeForces 236C LCM
    n为奇数时,必然最大的lcm就是n*(n-1)*(n-2)

    n为偶数时,判断一下lcm(n,n-1,n-3)还是(n-1)*(n-2)*(n-3)大

    或者只要判断n是否为3的倍数,如果是那么n,n-3有约数,那么肯定是后者最小公倍数大

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    #define ll long long
    
    int main()
    {
        ll n ;
        while(scanf("%I64d" , &n) == 1)
        {
            if(n<=2){
                printf("%I64d
    " , n);
                continue;
            }
            ll a,b,c;
            ll ans=0;
            if(n % 2==0){
                if(n%3 != 0) ans = n*(n-1)*(n-3);
                n--;
            }
    
            a=n,b=n-1,c=n-2;
            ans = max(ans , a*b*c);
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code

    3.CodeForces 231C maximum number of times
    这里数据量比较大,不能暴力来

    先从小到大排个序

    再记录一个前缀和,用来方便计算一部分数变成a[i]所需要的加的次数

    用两个指针 l , r 分别表示最左端和最右端,如果这一段可以全转化为 a[r] , 那么r++ , 否则 l++

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define ll long long
    const int N = 100005;
    ll sum[N] , a[N];
    int cnt , minn;
    
    bool ok(int l,int r , ll k)
    {
        ll time = a[r]*(ll)(r-l+1)-(sum[r]-sum[l-1]);
        if(time<=k){
            if(cnt < r-l+1) cnt = r-l+1,minn=a[r];
            return true;
        }
        return false;
    }
    
    int main()
    {
       // freopen("a.in" , "r" , stdin);
        ll n,k;
        while(scanf("%I64d%I64d" , &n , &k) == 2)
        {
            for(int i=1 ; i<=n ; i++)
            {
                scanf("%I64d" , a+i);
            }
            if(n==1){
                printf("%d %I64d
    " , 1 , a[1]);
                continue;
            }
            sort(a+1 , a+n+1);
            for(int i=1 ; i<=n ; i++)
            {
                sum[i] = sum[i-1] + a[i];
            }
            cnt=1 , minn=a[1];
            int l=1 , r=2;
            while(1){
                if(ok(l,r,k)) r++;
                else l++;
                if(r>n) break;
            }
            printf("%d %d
    " , cnt , minn);
        }
    
        return 0;
    }
    View Code

    4.POJ 3254 Fields

    一道简单的状态压缩dp

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define ll long long
    const int N = 15;
    const int M = 1<<13;
    const int MOD = 100000000;
    int dp[N][M];
    int a[N][M] , state[N];
    
    void dfs(int i , int v , int u , int k , int val)
    {
        if(k<0){
            dp[i][u] += val;
            dp[i][u]%=MOD;
            return;
        }
        if(!(v&(1<<k)) && state[i]&(1<<k))
            dfs(i , v , u|(1<<k) , k-2 , val);
        dfs(i , v , u , k-1 , val);
    }
    
    int main()
    {
       // freopen("a.in" , "r" , stdin);
        int n,m;
        while(scanf("%d%d" , &n , &m) == 2)
        {
            memset(dp , 0 , sizeof(dp));
            for(int i=1 ; i<=n ; i++)
            {
                state[i]=0;
                for(int j=1 ; j<=m ;j ++){
                    scanf("%d" , &a[i][j]);
                    state[i]<<=1;
                    state[i]+=a[i][j];
                }
            }
            dp[0][0] = 1;
            for(int i=1 ; i<=n ; i++){
                for(int j=0 ; j<(1<<m) ; j++){
                    if(dp[i-1][j]) dfs(i , j , 0 , m-1 , dp[i-1][j]);
                }
            }
            int ans = 0;
            for(int u=0 ; u<(1<<m) ; u++)
            {
                ans += dp[n][u];
                ans%=MOD;
            }
            printf("%d
    " , ans);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    定时器实现点击重新发送信息倒计时显示
    新浪微博5s钟后跳转页面
    时钟制作代码
    判断线段相交
    POJ1265:Area(多边形面积公式+pick公式) 好题
    ACM零散知识
    POJ2318:TOYS(叉积判断点和线段的关系+二分)&&POJ2398Toy Storage
    计算几何初步认识
    UVA10026:Shoemaker's Problem(贪心)
    UVA10020:Minimal coverage(最小区间覆盖)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4257058.html
Copyright © 2020-2023  润新知