你身上有一批装备,有一部分只能直接卖,有一部分既可以直接卖又可以用鉴定卷轴鉴定后再卖。现在告诉你所有的装备卖出去的价钱,以及鉴定卷轴的价钱,以及那些可以鉴定的装备鉴定后的价钱。鉴定卷轴是一次性的,再用还得在买。并且你不能赊账,即你在任意时刻钱都要大于零。你最开始没有任何钱。问你把所有装备都卖了能够得到的最大价钱。
首先我们可以把所有的直接卖比较好的物品都直接卖了,作为初始资金。其余物品用鉴定后价钱减去卷轴价钱作为鉴定后收益。这样只要我们不用鉴定卷轴卖的物品达到了鉴定卷轴的价钱,我们就能够得到剩余所有物品的鉴定后收益。
然后定义状态dp[i][j]表示假定已经有了鉴定卷轴,前i个剩余的物品中,不用鉴定卷轴直接卖的物品总共卖了j元钱,能够得到的最多的总收益。若j大于鉴定卷轴的钱,则可以统一置成鉴定卷轴的价钱。
#include <cstdio>
#include <cstring>
inline void in(int &x,int &y) {
char c=getchar();
x=y=0;
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
while (c<'0'||c>'9') {
if (c=='\n') return;
c=getchar();
}
while (c>='0'&&c<='9') {
y=y*10+c-'0';
c=getchar();
}
}
int n,m,newn,sum;
int a[1000];
int b[1000];
int dp[1001];
inline void update(int &a,int b) {
if (b>a) a=b;
}
int main() {
int i,j;
while (scanf("%d%d",&n,&m)!=EOF) {
getchar();
sum=newn=0;
for (i=0;i<n;i++) {
int x,y;
in(x,y);
if (x>=y-m) {
sum+=x;
} else {
a[newn]=x;
b[newn]=y-m;
newn++;
}
//printf("%d %d\n",x,y);
}
n=newn;
for (i=0;i<=m;i++) dp[i]=-1;
if (sum<m) dp[sum]=sum;
else dp[m]=sum;
for (i=0;i<n;i++) {
sum+=a[i];
if (dp[m]!=-1)
update(dp[m],dp[m]+b[i]);
for (j=m-1;j>=0;j--) {
if (dp[j]!=-1) {
if (j+a[i]<m)
update(dp[j+a[i]],dp[j]+a[i]);
else
update(dp[m],dp[j]+a[i]);
update(dp[j],dp[j]+b[i]);
}
}
}
if (dp[m]==-1) printf("%d\n",sum);
else printf("%d\n",dp[m]);
}
return 0;
}