Acwing 刷题3
AcWing 1211.蚂蚁感冒
思路
一直感冒的蚂蚁与另一只蚂蚁撞在一起,然后两个蚂蚁都感冒。这个过程可以看作两个蚂蚁互相穿过,也就是说可以看作那只感冒的蚂蚁行走的方向一直没有改变,那么在它行进的方向上与它方向相反的蚂蚁一定会感冒,而它身后的蚂蚁又会再次被感染。所以感冒的蚂蚁数量=第一只感冒的蚂蚁左边向右走的蚂蚁数量+右边向左走的蚂蚁数量+1。如果在感冒的蚂蚁前进的方向上没有相反方向的蚂蚁,那么一个蚂蚁都不会被感染,最终数量是1。
题解
#include<bits/stdc++.h>
using namespace std;
const int N=100;
int f[N],a[N];
int n,l1,l2,r1,r2,ans;
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
f[abs(a[i])]=a[i]>0?1:-1;
}
int k=abs(a[0]);
for(int i=1;i<k;i++)
{
if(f[i]==f[k]) l1++;
else if(f[i]!=0) l2++;
}
for(int i=k+1;i<100;i++)
{
if(f[i]==f[k]) r1++;
else if(f[i]!=0) r2++;
}
if(a[0]>0)
{
if(r2==0) ans=1;
else ans=l1+r2+1;
}
else
{
if(l2==0) ans=1;
else ans=l2+r1+1;
}
cout<<ans<<endl;
return 0;
}
AcWing 1216.饮料换购
思路
数据很小,直接循环
题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,ans=0;
cin>>n;
ans+=n;
while(n>=3)
{
ans+=n/3;
n=n/3+n%3;
}
cout<<ans<<endl;
return 0;
}
AcWing 2.01背包问题
思路
动态规划,f[i][j]表示的是在只考虑前i个物品且背包容量为j时所能装入的最大价值。
题解
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int v,w;//物品的体积和价值
cin>>v>>w; //输入第i个物品的体积和价值
for(int j=m;j>=v;j--)
f[j]=max(f[j],f[j-v]+w); //由于v>0,所以j-v<j,也就是说f[j-v]是i-1的状态而不是第i个状态
}
cout<<f[m]<<endl;
return 0;
}
AcWing 1015.摘花生
思路
动态规划,坐标为i,j的格子只能从上边或左边一个格子到达,f[i][j]表示在这个位置上所能摘到的最大花生数
题解
#include<bits/stdc++.h>
using namespace std;
const int N=1000;
int a[N][N],f[N][N];
int n,r,l;
int main()
{
cin>>n;
while(n--)
{
cin>>r>>l;
for(int i=1;i<=r;i++)
for(int j=1;j<=l;j++)
{
cin>>a[i][j];
f[i][j]=max(f[i-1][j],f[i][j-1])+a[i][j];
}
cout<<f[r][l]<<endl;
}
return 0;
}
AcWing 895.最长上升子序列
思路
动态规划,f[i][j]表示只考虑前i个数和后面的每个数能形成的最长子序列的长度
题解
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int a[N],f[N];
int n,ma;
int main()
{
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
for(int j=n;j>i;j--)
{
if(a[j]>a[i]) f[j]=max(f[j],f[i]+1);
}
for(int i=0;i<n;i++)
if(f[i]>ma) ma=f[i];
cout<<ma+1;
return 0;
}