hdu 6789-107 Fight 2020年百度の星・プログラム設計大会-初戦三

1867 ワード

http://acm.hdu.edu.cn/showproblem.php?pid=6789
http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=891&pid=1007
皆さんはこの問題ができますが、ただ私は知恵が弱いと同じように血液量dpを列挙しています.それから、血量と回数の関係方程式が解けません.
しかし列挙の回数はいいです.Lを0にしたいです.LとM、LとRの回数を列挙して彼を0にすればいいです.M-Rの回数を計算してM、Rの中の一つは0にして、解答を更新します.
Lは必ずしも0にならなくてもいいです.MとRが0になるので、二回します.
列挙が0になるのは、ちょうど0になります.何回かしか打つことができないので、もっと多く打つことができません.だから、一回少ない時は>0が必要です.
#include
#define pb push_back
using namespace std;
typedef long long ll;

const int maxl=3e5+10;

int n,m,cas,k,cnt,tot,ans;
int a,b,c;
char s[maxl];
bool in[maxl]; 

inline void prework()
{
	scanf("%d%d%d",&a,&b,&c);
} 

inline void mainwork()
{
	ans=1000;int resa,resb,resc,l,r;
	for(int i=0;i<=1000;i++)
		for(int j=0;j<=1000-i;j++) 
		if(1000-i*b-j*c<=0)
		{
			if(i>0 && (1000-(i-1)*b-j*c<=0 || 1000-(i-1)*a<=0))
				continue;
			if(j>0 && (1000-i*b-(j-1)*c<=0 || 1000-(j-1)*a<=0))
				continue;
			resb=1000-i*a;
			resc=1000-j*a;
			if(resb<=0 || resc<=0)
				ans=min(i+j,ans);
			else
			{
				l=resb/c+(resb%c!=0);
				r=resc/b+(resc%b!=0);
				ans=min(ans,i+j+min(l,r));
			}
		}
	for(int i=0;i<=1000;i++)
		for(int j=0;j<=1000-i;j++)
		if(1000-i*a-j*c<=0)
		{
			if(i>0 && (1000-(i-1)*a-j*c<=0 || 1000-(i-1)*b<=0))
				continue;
			if(j>0 && (1000-i*a-(j-1)*c<=0 || 1000-(j-1)*b<=0))
				continue;
			resa=1000-i*b; 
			resc=1000-j*b;
			if(resa<=0 || resc<=0)
				ans=min(i+j,ans);
			else
			{
				l=resa/c+(resa%c!=0);
				r=resc/a+(resc%a!=0);
				ans=min(ans,i+j+min(l,r));
			}
		}
}

inline void print()
{
	printf("%d
",ans); } int main() { int t=1; scanf("%d",&t); for(cas=1;cas<=t;cas++) { prework(); mainwork(); print(); } return 0; }