[USACO]奶牛會展(背包)
阿新 • • 發佈:2018-06-14
while 最好的 include 價值 證明 namespace turn read 輸入
但是有一點我們需要註意,在狀態轉移的過程中,智商和情商是允許為負數的,所以我們為了考慮到這種情況,將智商往右移\(sa\)個單位。
[USACO]奶牛會展
題目背景
奶牛想證明它們是聰明而風趣的。為此,貝西籌備了一個奶牛博覽會,她已經對N 頭奶牛進行
了面試,確定了每頭奶牛的智商和情商。
題目描述
貝西有權選擇讓哪些奶牛參加展覽。由於負的智商或情商會造成負面效果,所以貝西不希望出展奶牛的智商之和小於零,或情商之和小於零。滿足這兩個條件下,她希望出展奶牛的智商與情商之和越大越好,請幫助貝西求出這個最大值。
輸入輸出格式
輸入格式:
? 第一行:單個整數N,1 ≤ N ≤ 400
? 第二行到第N + 1 行:第i + 1 行有兩個整數:Si 和Fi,表示第i 頭奶牛的智商和情商,?1000 ≤ Si; Fi ≤ 1000
輸出格式:
輸出格式
? 單個整數:表示情商與智商和的最大值。貝西可以不讓任何奶牛參加展覽,如果這樣做是最好的,輸出0
輸入輸出樣例
輸入樣例#1:
5
-5 7
8 -6
6 -3
2 1
-8 -5
輸出樣例#1:
8
說明
選擇第一頭,第三頭,第四頭奶牛,智商和為?5+6+2 = 3,情商和為7?3+1 = 5。再加
入第二號奶牛可使總和提升到10,不過由於情商和變成負的了,所以是不允許的
被綠題支配的恐懼??? 最開始看到題目是懵逼的,之後看了題解才明白。將智商和情商分別看作容量和價值來做01背包。
\(F[i]\)表示當智商總和為\(i\)時,情商的最大值。
\[F[i]=max(F[i-a[k]]+b[k])\]
但是有一點我們需要註意,在狀態轉移的過程中,智商和情商是允許為負數的,所以我們為了考慮到這種情況,將智商往右移\(sa\)個單位。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int read()
{
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
int dp[800010],a[410],b[410];
int main()
{
int sa=0,ans=0;
int n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();b[i]=read();
if(a[i]>0) sa+=a[i];
}
sa=sa*2;
memset(dp,-0x3f,sizeof(dp));
dp[sa/2]=0;
for(int i=1;i<=n;i++)
{
if(a[i]>=0)
for(int j=sa;j>=a[i];j--)
{
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
}
else
for(int j=0;j<=sa-a[i];j++)
{
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
}
}
sa/=2;
for(int i=0;i<=sa;i++)
{
if(dp[i+sa]>=0)//這句判斷一定不能忘記了
ans=max(ans,i+dp[i+sa]);
}
cout<<ans;
}
[USACO]奶牛會展(背包)