码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1021: [SHOI2008]Debt 循环的债务

时间:2018-12-24 16:17:56      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:turn   continue   str   algo   fine   cal   print   --   abs   

抓准初始状态 末状态 考虑DP

 

/**************************************************************
    Problem: 1021
    User: lxy8584099
    Language: C++
    Result: Accepted
    Time:600 ms
    Memory:28440 kb
****************************************************************/
 
/*
    又是DP  多做多看吧。。。
    开始分别有sa,sb,sc   价换后分别是 ea,eb,ec  问最小交换几张钱 
    f[i][a][b] 表示用前i种钱 A目前有a元 B目前有B元(C目前是all-a-b元)
    所需要交换钱的最小张数 
    每次枚举交换之后 A的钱的张数aa B的钱的张数bb 
    那么交换的张数也能算出来了 
*/
#include<algorithm>
#include<cstdio> 
#include<cstring>
#define min(a,b) ((a>b)?(b):(a)) 
using namespace std;
const int N=1005;
int f[7][N][N],inf,mon[7]={0,1,5,10,20,50,100};
int numa[7],numb[7],numc[7],tot[7];
inline int cal(int a,int b,int k){//考虑第k种面额,最后A有a张,B有b张,c有tot-a-b张,需要交换几张达到。 
    return abs(a-numa[k])+abs(b-numb[k])+abs(tot[k]-a-b-numc[k])>>1;
}
 
int main()
{
    int x1,x2,x3,na=0,nb=0,nc=0,n,ea,eb,ec;
    scanf("%d%d%d",&x1,&x2,&x3);
    for(int i=6;i>=1;i--) 
        scanf("%d",&numa[i]),na+=mon[i]*numa[i],tot[i]+=numa[i];
    for(int i=6;i>=1;i--) 
        scanf("%d",&numb[i]),nb+=mon[i]*numb[i],tot[i]+=numb[i];
    for(int i=6;i>=1;i--) 
        scanf("%d",&numc[i]),nc+=mon[i]*numc[i],tot[i]+=numc[i];
    n=na+nb+nc;
    memset(f,0x3f,sizeof(f));
    inf=f[0][0][0];f[0][na][nb]=0;
    ea=na-x1+x3;eb=nb-x2+x1;ec=nc-x3+x2;
    for(int k=0;k<6;k++)
    for(int i=0;i<=n;++i)
    for(int j=0;i+j<=n;++j)
    {
        if(f[k][i][j]==inf) continue;
        // 无法达到这个状态 
        for(int a=0;a<=tot[k+1];++a)
        for(int b=0;b+a<=tot[k+1];++b)
        {
            int ii=i+mon[k+1]*(a-numa[k+1]);
            int jj=j+mon[k+1]*(b-numb[k+1]);
            if(ii>=0&&jj>=0&&ii+jj<=n)
                f[k+1][ii][jj]=min(f[k+1][ii][jj],
                f[k][i][j]+cal(a,b,k+1));
        }
    }
    if(f[6][ea][eb]==inf) puts("impossible");
    else printf("%d\n",f[6][ea][eb]);
    return 0;
}

 

bzoj 1021: [SHOI2008]Debt 循环的债务

标签:turn   continue   str   algo   fine   cal   print   --   abs   

原文地址:https://www.cnblogs.com/lxy8584099/p/10168525.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!