zoukankan      html  css  js  c++  java
  • [luogu4026 SHOI2008]循环的债务 (DP)

    传送门
    吐槽洛谷难度标签qwq

    Solution

    显然是一道神奇的DP,由于总钱数不变,我们只需要枚举前两个人的钱数就可知第三个人的钱数
    DP的时候先枚举只用前k个币种,然后枚举前两个人的钱数,然后枚举转移即可

    Code

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define F(i,a,b) for(register int i=(a);i<=(b);i++)
    using namespace std;
    
    inline int read() {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    
    const int N=1010,INF=0x3f3f3f3f;
    int p[7]={0,100,50,20,10,5,1};
    int sum,s1,s2,x1,x2,x3,ans;
    int f[7][N][N],num[4][7];
    
    int main() {
    	x1=read(),x2=read(),x3=read();
    	F(i,1,3) F(j,1,6) sum+=(num[i][j]=read())*p[j];
    	F(i,1,6) s1+=num[1][i]*p[i],s2+=num[2][i]*p[i];
    	if(s1-x1+x3>sum||s2-x2+x1>sum||sum-s1-s2-x3+x2>sum) 
    		return puts("impossible"),0;
    	memset(f,0x3f,sizeof(f));f[0][s1][s2]=0;
    	F(k,1,6) {
    		int tot=num[1][k]+num[2][k]+num[3][k];
    		F(i,0,sum) F(j,0,sum-i) {
    			if(f[k-1][i][j]==INF) continue;
    			F(x,0,tot) F(y,0,tot-x) {
    				int z=tot-x-y;
    				int s=(abs(num[1][k]-x)+abs(num[2][k]-y)+abs(num[3][k]-z))/2;
    				int d1=i-(num[1][k]-x)*p[k],d2=j-(num[2][k]-y)*p[k];
    				if(d1+d2>sum) continue; if(d1<0||d2<0) continue;
    				f[k][d1][d2]=min(f[k][d1][d2],f[k-1][i][j]+s);
    			}
    		}
    	} 
    	int ans=f[6][s1-x1+x3][s2-x2+x1];
    	if(ans==INF) return puts("impossible"),0;
    	return printf("%d",ans),0;
    }
    
  • 相关阅读:
    第三篇 从EXCEL电子表格到数据库
    第二篇 顾问实施ERP与医生看病过程类比
    第一篇 ERP是什么?-从道的层面浅谈我的理解
    Order to Cash Process
    Back to Back Order Process
    OracleApps 什么是Back to Back Order?
    三方贸易-drop ship
    Oracle Order Management DropShip Flow for R12
    OracleApps Dropship 流程
    geetoo编译安装
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9737435.html
Copyright © 2011-2022 走看看