截止目前(2023.6.27)本题共37提交40通过,无题解。 根据本人做题时的思考与某大佬讨论帖发表此讨论。
首先,本题与UVa10833几乎一样,而那道题的暴力法AC代码仅修格式改后在本题60pts,贪心法WA代码仅修改格式后100pts。(详见上述讨论帖)
而贪心法的答案普遍>=暴力法。同时经过蒟蒻本人手动演算, 暴力法的答案是正确的。 结合两道几乎一致的题对于相同代码答案结果判定不同,本人合理怀疑此题数据答案是否正确。
声明:本人同样写了一种贪心代码AC此题,和上述讨论帖内的贪心代码思路略有不同,但经过500组数据对拍结果全部一样,为此应该可以代表贪心算法。本人具体贪心方法不详写,肯定不是因为懒,可以参考上述讨论贴的方法。
比如数据5 7 9。 暴力算法和贪心算法在前7天的施肥方法是一样的。最后得到的月亮树高度依次是:10 6 5 1 0 -1 -1 -1 -1(-1表示尚未播种)
此时,贪心算法会给第3棵月亮输施肥。使第八天时第三棵树达到高度h2从而获得种子。
第八天:11 7 7 2 1 0 0 -1 -1
第九天:12 8 8 4 2 1 1 -1 -1
第十天:13 9 9 6 3 2 2 0 -1
第十一天:14 10 10 7 5 3 3 1 0
此时答案为:4+4+7+9+11+11+13+14+11=84
第八天:11 7 6 3 1 0 -1 -1 -1
第九天:12 8 7 5 2 1 0 0 -1
第十天:13 9 8 7 3 2 1 1 0
此时答案为:4+5+6+10+11+12+12+13+10=83
贪心算法会优先选择给能更快到达h1或h2的月亮树施肥,从而更快获得种子。但这仅是局部最优。因为月亮树达到h2之后的生长不能再带来种子收益。
倘若先给其他月亮树施肥达到h1乃至h2,于此同时高的月亮树会自然生长到h2。从而在同样的时间内获得更多种子,从而得到更短的答案。
为此,这种贪心方法不能得到正确的答案。
最后,附上本人代码(AC此题,但答案应该不对)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=102;
int h1,h2,n,ans,a[N],t1=2,t2=3,g,sum,st=4;
bool _;
int main()
{
scanf("%d%d%d",&h1,&h2,&n);
if(h1>h2) swap(h1,h2);
if(h1&1){
sum=h1/2+1;
a[1]=h1+1+sum;
a[2]=h1;g=1;
}
else{
sum=h1/2;
a[1]=h1+sum;
a[2]=h1;
}
ans=sum*2;
if(a[1]>=h2) _=1,a[3]=a[1]-h2,st=5;
if(a[1]<=h2) a[2]+=g,g=0;
if(h1==h2&&(h1&1)) a[3]--;
for(int i=st;i<=n;i++){
int num1=h2-a[t1]-g;
int num2=h1-a[t2]-g;
if(a[t2]==0) num2+=g;
if((num1+1)/2<(num2+1)/2){
g=0;
sum=(num1+1)/2;
if(num1&1) g=1;
a[t1++]=h2-sum;
}
else{
if(a[t2]==0) a[t1]+=g;
g=0;
sum=(num2+1)/2;
if(num2&1) g=1;
a[t2++]=h1-sum;
}
if(a[1]+sum>=h2&&!_)
_=1,a[i++]=a[1]-h2;
for(int j=1;j<i;j++) a[j]+=sum;
ans+=sum;
}
for(int i=2;i<=n;i++) ans+=a[1]-a[i];
printf("%d",ans-g);
return 0;
}