• [bzoj1021][SHOI2008]Debt 循环的债务【dp】


    【题目链接】
      http://www.lydsy.com/JudgeOnline/problem.php?id=1021
    【题解】
      记 f[i][j][k] 表示考虑到第 i 中面额的钞票,A当前盈利了 j 元,B当前盈利了 k 元,最少盈利的钱数。
      转移是,在第 i 轮中,枚举A付出了 i1 张该面额钞票,B付出了 i2 张该面额的钞票。
      时间复杂度 O(100026302) 实际远远不到。
      tips:从小的往大的搜,这样比较多的一开始就搜完了,比较优。
      

    /* --------------
        user Vanisher
        problem bzoj-1021 
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    # define    T       1000
    # define    N       2050
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    
    const int p[7]={0,100,50,20,10,5,1};
    short int f[7][N][N];
    int num1[2][N*N],num2[2][N*N],r[4],h[4][7],sum[7],pr[2];
    bool mp[7][N][N];
    int main(){
        int a=read(), b=read(), c=read();
        r[1]=c-a, r[2]=a-b, r[3]=b-c;
        if (r[1]>T||r[2]>T||-r[1]>T||-r[2]>T){
            printf("impossible
    ");
            return 0;
        }
        for (int i=1; i<=3; i++)
            for (int j=1; j<=6; j++)
                h[i][7-j]=read(), sum[7-j]+=h[i][7-j];
        memset(f,inf,sizeof(f));
        int f1=0, f2=1;
        short int ans=inf%65536;
        f[0][T][T]=0; pr[f1]=1; num1[f1][1]=T; num2[f1][1]=T; 
        for (int i=1; i<=6; i++){
            for (int i1=-h[1][i]; i1<=sum[i]-h[1][i]; i1++)
                for (int i2=-h[2][i]; i2<=sum[i]-h[2][i]; i2++){
                    if (i1+i2>h[3][i]) continue;
                    for (int j=1; j<=pr[f1]; j++){
                        int now1=num1[f1][j]+p[7-i]*i1,
                            now2=num2[f1][j]+p[7-i]*i2;
                        f[i][now1][now2]=min((int)f[i][now1][now2],f[i-1][num1[f1][j]][num2[f1][j]]+max(max(abs(i1+i2),abs(i1)),abs(i2)));
                        if (f[i][now1][now2]<ans&&mp[i][now1][now2]==false){
                            mp[i][now1][now2]=true;
                            num1[f2][++pr[f2]]=now1, num2[f2][pr[f2]]=now2;
                        }
                    }
                }
            swap(f1,f2);
            pr[f2]=0;
            ans=min(ans,f[i][r[1]+T][r[2]+T]);
        }
        if (ans==inf%65536)
            printf("impossible
    ");
            else printf("%hd
    ",ans);   
        return 0;
    }
    
  • 相关阅读:
    监控系统
    RocketMQ入门介绍
    Linux的虚拟内存详解(MMU、页表结构) 转
    快速排序
    如何选择分布式事务解决方案? 转
    java 基本数据类型相关思考
    互联网项目中mysql应该选什么事务隔离级别 转
    线上服务的FGC问题排查,看这篇就够了! 转
    什么是Base64? 转
    业界难题-“跨库分页”的四种方案 转
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9136002.html
Copyright © 2020-2023  润新知