P1050 精卫填海
【问题描述】
发鸠之山,其上多柘木。有鸟焉,其状如乌,文首,白喙,赤足,名曰精卫,其名自詨。是炎帝之少女,名曰女娃。女娃游于东海,溺而不返,故为精卫。常衔西山之木石,以堙于东海。——《山海经》
精卫终于快把东海填平了!只剩下了最后的一小片区域了。同时,西山上的木石也已经不多了。精卫能把东海填平吗?
事实上,东海未填平的区域还需要至少体积为v的木石才可以填平,而西山上的木石还剩下n块,每块的体积和把它衔到东海需要的体力分别为k和m。精卫已经填海填了这么长时间了,她也很累了,她还剩下的体力为c。
这题是让我们用最小的体力搬最大的体积。
我一开始没用最小的体力,
就对了一个点
很尴尬😥
看看我只对了一个点的代码吧:
#include<iostream> #include<cstdio> using namespace std; int v,n,c,ans; int f[10000],tj[10000],tl[10000]; int main() { cin>>v>>n>>c; for(int i=0;i<n;i++) { cin>>tj[i]; cin>>tl[i]; } ans=c;//记剩余体力的变量 for(int i=0;i<n;i++) { for(int j=c;j>=0;j--) { if(j>=tl[i])//是否有足够的体力搬运 { if(f[j-tl[i]]+tj[i]>f[j])//搬过来是否体积会更大 { f[j]=f[j-tl[i]]+tj[i]; if(j==c)//是否体力为c { //cout<<ans<<" "<<i<<endl; ans-=tl[i];//减去需要的体力 //cout<<ans<<endl; } } } } } //cout<<f[c]<<" "<<n<<endl; if(v-f[c]>0)//如果不能填完,输出 Impossible { cout<<"Impossible"<<endl; return 0; } cout<<ans<<endl;//输出剩余的体力 return 0; }
在死磕了几天后
突然发现我求的是体力为c,谁出填完剩余最多的体力
我改了代码:
#include<iostream> #include<cstdio> using namespace std; int v,n,c; int f[10000],tj[10000],tl[10000]; int main() { cin>>v>>n>>c; for(int i=0;i<n;i++) { cin>>tj[i]; cin>>tl[i]; } for(int i=0;i<n;i++) { for(int j=c;j>=0;j--) { if(j>=tl[i])//是否有足够的体力搬运 { f[j]=max(f[j-tl[i]]+tj[i],f[j]);//求出当前体力最多可以搬运的最大体积 } } } for(int i=0;i<c;i++)//循环,搜索可以填满的最小体力 { if(f[i]>=v)//如果填满了,就输出剩余的体力 { cout<<c-i<<endl; return 0; } } cout<<"Impossible"<<endl; return 0; }
然后,就A了(*^-^*)