DP思路:先拿5元出来,对价格排序,把最大的先放一边,对剩下的01背包。
状态转移方程: dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
注意:
1、n=1时直接输出m-a[0];
2、m<5时输出m;
3、其余情况01背包
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long #define fo freopen("in.txt","r",stdin) #define fc fclose(stdin) #define fu0(i,n) for(i=0;i<n;i++) #define fu1(i,n) for(i=1;i<=n;i++) #define fd0(i,n) for(i=n-1;i>=0;i--) #define fd1(i,n) for(i=n;i>0;i--) #define mst(a,b) memset(a,b,sizeof(a)) #define sd(n) scanf("%d",&n) #define sdd(n,m) scanf("%d %d",&n,&m) #define ss(s) scanf("%s",s) #define sddd(n,m,k) scanf("%d %d %d",&n,&m,&k) #define pans() printf("%d\n",ans) #define all(a) a.begin(),a.end() #define sc(c) scanf("%c",&c) const int maxn=200005; const double eps=1e-8; int main() { int n,m; while(cin>>n&&n) { int a[1005]; int dp[1005]={0}; int i,j; int sum=0; for(i=0;i<n;i++) { sd(a[i]); } sd(m); if(m<5) cout<<m<<endl; else if(n==1) cout<<m-a[0]<<endl; else { sort(a,a+n); for(i=0;i<n-1;i++) { for(j=m-5;j>=a[i];j--) { dp[j]=max(dp[j],dp[j-a[i]]+a[i]); } } int ans; ans=m-dp[m-5]-a[n-1]; cout<<ans<<endl; } } return 0; }