A1007
//需要注意的是,如果结果为负数,将值改为0 后面输出的是 这一段最大值中的第1个值和最后一个值,不是下标
#include<iostream>
using namespace std;
const int maxn=10010;
int n;
int w[maxn];
int main()
{
cin >> n;
for(int i=1; i<=n; i++)
cin >> w[i];
int res=-1,l,r;
for(int i=1,f=-1,start; i<=n; i++) //f表示的意思是 以i为右端点 的区间 内的 一段值得和,并且这个和是最大的
{
if(f<0) //表示此时以i为右端点的区间 内的一段 和是 小于0,需要更新
{
f=0;
start=i;
}
f+=w[i]; //f=w[i]+max(0,f); // f=max(w[i],f+w[i]);
if(res<f) //res表示最终结果,如果res小于此时以i为右端点的区间最大值,需要更新
{
res=f;
l=w[start],r=w[i]; //r为i,因为现在是 更新值了,而此时 更新的 最大值 的 右端点就是 i
}
}
if(res<0)
{
res=0;
l=w[1];
r=w[n];
}
cout << res << " " << l << " " << r;
return 0;
}
A1045
#include<iostream>
using namespace std;
const int maxn=10010;
int n,m,l;
int p[maxn],s[maxn];
int f[maxn][maxn];
int main()
{
cin >> n >> m;
for(int i=1; i<=m; i++)
cin >> p[i];
cin >> l;
for(int i=1; i<=l; i++)
cin >> s[i];
for(int i=1; i<=m; i++)
for(int j=1; j<=l; j++)
{
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(p[i]==s[j])
f[i][j]=max(f[i][j],f[i][j-1])+1;
}
cout << f[m][l];
return 0;
}
A1068
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=10010;
int n,m;
int a[maxn];
bool f[maxn][maxn];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
cin >> n >> m;
for(int i=1; i<=n; i++)
cin >> a[i];
sort(a+1,a+n+1,cmp);
f[0][0]=true; //0个物体,重量为0 肯定是存在的
for(int i=1; i<=n; i++)
for(int j=0; j<=m; j++)
{
f[i][j]=f[i-1][j];
if(j>=a[i]) //本来是f[i][j]=f[i-1][j]|f[i-1][j-a[i]] 但是j与a[i]要单独判断,所以才会有下面的判断 | 或运算是 只要有一个为真,就为真
//f[i][j] |= f[i-1][j-a[i]]; 上下两行代码相同
f[i][j] = f[i][j] |f[i-1][j-a[i]]; //f[i][j]只有这两种情况 ,不是第1个就是第2个
}
if(f[n][m]==false)
{
cout << "No Solution" << endl;
}
else
{
bool flag=true;
while(n)
{
if(m>=a[n] && f[n-1][m-a[n]])
{
if(flag)
flag=false;
else
cout << " ";
cout << a[n];
m-=a[n];
}
n--;
}
}
return 0;
}
A1093
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=100010;
const int INF=1e9+7;
char p[5]=" PAT";
char s[maxn];
int f[maxn][4];
int main()
{
cin >> s+1;
int n=strlen(s+1);
f[0][0]=1;
for(int i=1; i<=n; i++)
for(int j=0; j<=3; j++)
{
f[i][j]=f[i-1][j]; //先让f[i][j] =f[i-1][j] 表示不取第i个字符
if(s[i]==p[j]) //表示取第i个字符
f[i][j]=(f[i][j]+f[i-1][j-1])%INF; //f[i-1][j]+f[i-2][j-1] 前面表示前i-1个字符走到了状态j,目前取第i个字符,需要从状态j-1走到状态j,那就是f[i][j]又取了第i个字符,所以为f[i-1][j-1]
}
cout << f[n][3];
return 0;
}
A1101
#include<iostream>
using namespace std;
const int maxn=100010;
int L[maxn],R[maxn],ans[maxn];
int n;
int main()
{
cin >> n;
for(int i=0; i<n; i++)
cin >> ans[i];
L[0]=0;
for(int i=1; i<n; i++)
{
L[i]=max(L[i-1],ans[i-1]);
}
R[n-1]=0x3fffffff;
for(int i=n-2; i>=0; i--)
{
R[i]=min(R[i+1],ans[i+1]);
}
int num=0;
int res[maxn];
for(int i=0; i<n; i++)
{
if(L[i]<ans[i] && ans[i]<R[i])
{
res[num++]=ans[i];
}
}
cout << num << endl;
for(int i=0; i<num; i++)
{
if(i!=0)
cout << " ";
cout << res[i];
}
cout << endl; //如果得到个数为0,需要输出一个空格,不然就扣4分
return 0;
}