题目是01背包的变形。刚开始没看出来。Wrong了好几次!!
当卡上金额大于等于5元时才能购买成功,我们不妨将这里的5元视为“0“,因为在DP过程中金额不能低于5,所以最后要用到的结果应该是dp[m-5]。既然我们保证了余额一直是大于等于5的,那么最后还能购买一次,所以,我们将最贵的一样菜留在最后,在DP的过程结束之后再购买,这样就能保证最后的余额最少。
这样也是可以的,只是要注意最后结果应该使用dp[m],而不是dp[m+5],开始由于使用了dp[m+5],所以WA了。j从m+5到5,也是为了保证不小于5元,但是实际上m to 5就行了。
#include"stdio.h" #include"string.h" int dp[1001]; int MAX(int x,int y) { return x>y?x:y; } int main() { int n,m,a[1001],i,j,max,jj; while(scanf("%d",&n)!=-1&&n) { max=0; for(i=0;i<n;i++) { scanf("%d",&a[i]); if(max<a[i]) { max=a[i];jj=i; } } scanf("%d",&m); if(m<5) printf("%d\n",m); else { memset(dp,0,sizeof(dp)); for(i=0;i<n;i++) { for(j=m+5;j>=5;j--) if(j-a[i]>=5&&i!=jj) dp[j]=MAX(dp[j],dp[j-a[i]]+a[i]); } printf("%d\n",m-dp[m]-a[jj]); } } return 0; }