BZOJ 1021 循环的债务

DP出各种状态

#include <iostream>

using namespace std;

const int INF=1034567890;
const int Lim=1000000000;

int x1, x2, x3;
int M=1000;
int A=0, B=0, C=0;
int aimA, aimB, aimC;
int Am[7], Bm[7], Cm[7], Tot[7];
int Val[7]={0, 1, 5, 10, 20, 50, 100};
int F[7][1111][1111];

int abs(int a){
return (a<0)?(-a):a;
}

int dis(int a, int b, int at){
return (abs(a-Am[at])+abs(b-Bm[at])+abs(Tot[at]-a-b-Cm[at]))/2;
}

int main(){
ios_base::sync_with_stdio(false);

cin >> x1 >> x2 >> x3;

for(int i=6;i>=1;--i)	cin >> Am[i], Tot[i]+=Am[i];
for(int i=1;i<=6;++i)	A+=Am[i]*Val[i];
aimA=A-x1+x3;

for(int i=6;i>=1;--i)	cin >> Bm[i], Tot[i]+=Bm[i];
for(int i=1;i<=6;++i)	B+=Bm[i]*Val[i];
aimB=B+x1-x2;

for(int i=6;i>=1;--i)	cin >> Cm[i], Tot[i]+=Cm[i];
for(int i=1;i<=6;++i)	C+=Cm[i]*Val[i];
aimC=C-x3+x2;

M=A+B+C;

for(int i=0;i<7;++i)
for(int j=0;j<1111;++j)
for(int k=0;k<1111;++k)	F[i][j][k]=INF;

F[0][A][B]=0;
for(int i=0;i<6;++i)
for(int j=0, jj;j<=M;++j)
for(int k=0, kk;k+j<=M;++k){
if(F[i][j][k]>Lim)	continue;
for(int a=0;a<=Tot[i+1];++a)
for(int b=0;a+b<=Tot[i+1];++b){
jj=j+Val[i+1]*(a-Am[i+1]);
kk=k+Val[i+1]*(b-Bm[i+1]);
if(jj>=0 && kk>=0 && jj+kk<=M)
F[i+1][jj][kk]=min(F[i+1][jj][kk], F[i][j][k]+dis(a, b, i+1));
}
}

if(F[6][aimA][aimB]<=Lim)	cout << F[6][aimA][aimB] << endl;
else	cout << "impossible" << endl;

return 0;
}

/*
10 0 0
0 1 0 0 0 0
0 0 0 3 0 10
0 0 3 0 0 0

5

*/

/*
-10 -10 -10
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

0

*/
posted @ 2018-03-28 13:44  Pickupwin  阅读(145)  评论(0编辑  收藏  举报