2.Max Sum 最大子串和
题目:求最大子串和,并求区间[l,r]
思路:原始数组为 a[i] , 我们就用 a[i] 来表示以 i 结尾的最大子串和。
a[i-1] >=0 ,就说明对 a[i] 是有贡献的(能让a[i]更加大)。
a[i-1] <0 ,就说明没有贡献,记录此时下标(因为找到更大的a[k]时此时下标就是左区间)。
循环时更新ans=max()即可。
#include<bits/stdc++.h>
using namespace std;
int dp[100005];//dp[i]是以i为结尾的最大值
int main(){
int t,n;
cin>>t;
for(int m=1;m<=t;m++){
cin>>n;
for(int i=1;i<=n;i++)
cin>>dp[i];
int maxn=dp[1],left=1,right=1;//区间
int temp=1;//记录起点
for(int i=2;i<=n;i++){
if(dp[i-1]>=0)
dp[i]=dp[i]+dp[i-1];
else
temp=i;
if(dp[i]>maxn){
left=temp;
right=i;
maxn=dp[i];
}
}
if(m>=2)cout<<endl;
printf("Case %d:\n",m);
cout<<maxn<<" "<<left<<" "<<right<<endl;
}
return 0;
}
3.Super Jumping! Jumping! Jumping! 递增子序列最大和
题目:
给出一个原始序列,在序列里面找一个递增的序列并且这个序列的和最大。(如1 3 10 5 6 4:sum=1+3+5+6 = 15)
思路:
这里我们是自顶向下,采用记忆化搜索。
dp[i] 是以 i 为开始的到末尾的最大和。
我们知道只有当 i 后面的某一个元素 a[k] > a[i] 时,就能够取 a[k],即dp[i] = dp[k] + a[k] 。也就是说我们前状态 dp[i] 的最大值取决于它后状态的最大值: dp_max(dp[k…n])。 采用递归的方式。
/*
2020/05/25
*/
#include<bits/stdc++.h>
using namespace std;
#define fori(a,b) for(int i=a;i<=b;i++)
#define ifor(a,b) for(int i=a;i>=b;i--)
#define mem(a,b) memset(a,b,sizeof(a));
#define ma 1e3+5
const int maxn=1e3+5;
int n,a[maxn],dp[maxn];
int dfs(int x){
if(dp[x])return dp[x];
int maxx=0;
fori(x+1,n)
if(a[i]>a[x])
maxx=max(maxx,dfs(i));
dp[x]=maxx+a[x];
return dp[x];
}
int main(){
while(cin>>n){
if(!n)break;
mem(dp,0);
fori(1,n)cin>>a[i];
int ans=0;
fori(1,n)
ans=max(ans,dfs(i));
cout<<ans<<endl;
}
return 0;
}
4.Piggy-Bank 完全背包最小价值
题目:
每一个硬币有一定重量 w[i] 和价值 v[i] ,求一定重量 m 能拿的最小价值。
思路:
完全背包求最小的价值。要判断 m 是否 为 0 或者是否能拿到重量 m。
/*
2020/05/25
*/
#include<bits/stdc++.h>
using namespace std;
#define fori(a,b) for(int i=a;i<=b;i++)
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 1e9+7
const int maxn=1e4+5;
int main(){
int t,a,b,n,v[505],w[505],dp[maxn];
cin>>t;
while(t--){
cin>>a>>b>>n;
b-=a;
fori(1,b)
dp[i]=inf;
for(int i=1;i<=n;i++)
cin>>v[i]>>w[i];
if(!b)dp[b]=0;
else{
for(int i=1;i<=n;i++)
for(int j=w[i];j<=b;j++)
dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
}
if(dp[b]==inf)//拿不到这个重量
printf("This is impossible.\n");
else
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[b]);
}
return 0;
}
/*
一定的重量求最小的价值
完全背包的最小价值
*/
5.Common Subsequence 最长公共子序列
/*
2020/05/26
*/
#include<bits/stdc++.h>
using namespace std;
#define fori(a,b) for(int i=a;i<=b;i++)
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f
const int maxn=1e3+5;
int dp[maxn][maxn];
int Lcs(string a,string b){
mem(dp,0);
for(int i=1;i<=a.size();i++)
for(int j=1;j<=b.size();j++){
if(a[i-1]==b[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else if(dp[i-1][j]>dp[i][j-1])
dp[i][j]=dp[i-1][j];
else
dp[i][j]=dp[i][j-1];
}
return dp[a.size()][b.size()];
}
int main(){
string a,b;
while(cin>>a>>b){
cout<<Lcs(a,b)<<endl;
}
return 0;
}