acm专题六
一、第一题
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i,n,sum=-100000,a,ans=-100000;
cin>>n;
for(i=0;i<n;i++)
{
cin>>a;
if(sum<=0) sum=a;
else sum+=a;
if(sum>ans) ans=sum;
}
cout<<ans;
return 0;
}
思路:假设每次输入的数都是下一段的开头,如果此时和小于零,证明这段不符,从下一段开始,反之则可以继续延长这段
二、第二题
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i,T,M,t[101],v[101],j,dp[1005]={0};
cin>>T>>M;
for(i=1;i<=M;i++) cin>>t[i]>>v[i];
for(i=1;i<=M;i++)
for(int tt=T;tt>=t[i];tt--)
dp[tt]=max(dp[tt],dp[tt-t[i]]+v[i]);
cout<<dp[T];
return 0;
}
思路:遍历每种草药,倒着遍历足够时间,对取与不取两个情况判断
三、第三题
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,W,i,j,m=1,vv,ww,mm;
cin>>n>>W;
vector<int> v,w;
for(i=0;i<n;i++)
{
cin>>vv>>ww>>mm;
for(j=1;j<=mm;j<<=1) v.push_back(j*vv),w.push_back(j*ww),mm-=j;
if(mm) v.push_back(mm*vv),w.push_back(mm*ww);
}
vector<int> dp(W+1,0);
for(i=0;i<v.size();i++)
for(int weight=W;weight>=w[i];weight--)
dp[weight]=max(dp[weight],dp[weight-w[i]]+v[i]);
cout<<dp[W];
return 0;
}
思路:将背包问题二进制优化
四、第四题
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,i,j,mapp[100001];
cin>>n;
vector<int> first(n),second(n),dp(n,100001);
for(i=0;i<n;i++) cin>>first[i],mapp[first[i]]=i;
for(i=0;i<n;i++) cin>>second[i],second[i]=mapp[second[i]];
int ans=0,m=100001;
for(i=0;i<n;i++) { auto it=upper_bound(dp.begin(),dp.end(),second[i]);*it=second[i];}
for(i=0;i<n;i++)
if(dp[i]!=100001) ++ans;
else break;
cout<<ans;
return 0;
}
思路:用mapp数组将求解最大子序列转化为求解最大连续上升子序列
总结:dp关键在于状态转移方程和优化,so hard hard hard

浙公网安备 33010602011771号