Gym 100963B
啊,郁闷,就tm调小了一点范围就A了,就写dp和贪心比较一下,范围到最大值的二倍-1就好了
假设最大值的2倍以内能满足最优条件,当金额范围超过最大值2倍的时候;
至于为什么,还不清楚,再想想
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<set> #include<map> #include<stack> #include<cstring> #define inf 2147483647 #define ls rt<<1 #define rs rt<<1|1 #define lson ls,nl,mid,l,r #define rson rs,mid+1,nr,l,r #define N 100010 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() using namespace std; int n; int f[10010]; int a[100]; bool flag; int cnt; int greedy,dp; void in(int &x){ int y=1; char c=g();x=0; while(c<'0'||c>'9'){ if(c=='-')y=-1; c=g(); } while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=g(); } x*=y; } void o(int x){ if(x<0){ p('-'); x=-x; } if(x>9)o(x/10); p(x%10+'0'); } void clear(){ For(i,1,10000){ f[i]=inf; } greedy=0; } int get1(int x){ int r=0; for(int i=n;i;i--){ r+=x/a[i]; x%=a[i]; } return r; } int get2(int x){ //f[0]=1; For(i,1,n) For(j,a[i],x) f[j]=min(f[j],f[j-a[i]]+1); return f[x]; } int main(){ while(cin>>n&&n!=0){ For(i,1,n) in(a[i]); if(a[1]!=1){ cout<<"Case #"<<++cnt<<": Cannot pay some amount"<<endl; continue; } clear(); For(i,1,a[n]*2-1){ greedy=get1(i); dp=get2(i); if(greedy!=dp){ cout<<"Case #"<<++cnt<<": Cannot use greedy algorithm"<<endl; //cout<<i<<" "<<greedy<<" "<<dp<<endl; break; } } if(greedy!=dp) continue; cout<<"Case #"<<++cnt<<": OK"<<endl; } return 0; }