简化版
原题:zjnu 1286
题意:
x轴上有连续的n个鱼塘,每个鱼塘开始五分钟可以得到f[i]的鱼,每获得五分钟的鱼,获得鱼的数量减少d[i],到0为止,第i个鱼塘前位第i+1个鱼塘的时间为t[i]*5,问h小时可以获得的最多的鱼
解析:
dp的做法,dp[i][j]表示j个5分钟后呆在i鱼塘的最优解
状态转移方程:
dp[i][k]=dp[i-1][k-t[i-1]]
:k时间到达i鱼塘dp[i][k+j]=dp[i][k]+f[i]-j*d[i]
:在k时间到达i鱼塘并花了j个5分钟
代码:
#define for1(i,a,b) for(int i=a;i<=b;i++)
D read(){ D ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
int n,h;
int f[30],d[30],t[29];
int dp[30][300];
int main(){
mmm(dp,0);
n=read(),h=read(),h*=12;
for1(i,1,n)f[i]=read();
for1(i,1,n)d[i]=read();
for1(i,1,n-1)t[i]=read();
dp[1][0]=0;
for1(i,1,h){
int s=i-1;
s=f[1]-d[1]*s;
s=max(s,0);
dp[1][i]=dp[1][i-1]+s;
}
for1(i,2,n){
int comt=0;
for(int j=1;j<i;j++)comt+=t[j];
for1(j,comt,h){
dp[i][j]=max(dp[i][j],dp[i-1][j-t[i-1]]);
int tmp=dp[i-1][j-t[i-1]];
//必须要用dp[i-1][j-t[i-1]]来进行下一步的计算
for1(k,j+1,h){
int s=k-j-1;
s=f[i]-d[i]*s;
s=max(s,0);
tmp+=s;
dp[i][k]=max(dp[i][k],tmp);
}
}
}
int ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,dp[i][h]);
}
printf("%d\n",ans);
}
加强版
题意:
在上述的基础上,需要额外输出在每个鱼塘呆的时间
解析:
贪心做法:
枚举最后一个到达的鱼塘,既然知道了最后一个鱼塘,那么花费在路上的时间就可以求出来了,然后剩下的时间每次对这些鱼塘下一个5分钟可以获得的鱼取一个最大值
代码:
#define for1(i,a,b) for(int i=a;i<=b;i++)
D read(){ D ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
int ti,n,h;
int f[30],d[30],t[30];
int Time[30];
int ans=-1;
void fin(int r){
int u=h-t[r-1];if(u<=0)return;
int tmp[30],out[30];
mmm(out,0);
for(int i=1;i<=r;i++)tmp[i]=f[i];
int re=0;
while(u){
int ar=1,m=tmp[1];
for(int i=2;i<=r;i++)
if(tmp[i]>m){
m=tmp[i];ar=i;
}
re+=tmp[ar];
tmp[ar]-=d[ar];if(tmp[ar]<0)tmp[ar]=0;out[ar]++;
u--;
}
if(re>ans){
ans=re;for(int i=1;i<=n;i++)Time[i]=out[i];
}
}
int main(){
ti=read();int ca=0;while(ti--){
ans=-1;//don't forget this
n=read(),h=read(),h*=12;
for1(i,1,n)f[i]=read();
for1(i,1,n)d[i]=read();
for1(i,1,n-1)t[i]=read(),t[i]+=t[i-1];
for1(i,1,n)fin(i);
printf("Case %d:\n",++ca);
for1(i,1,n){
if(i!=n)printf("%d, ",Time[i]*5);
else printf("%d\n",Time[i]*5);
}
printf("Number of fish expected: %d\n",ans);
}
}