题解是用dp,我们是联想到了走楼梯问题,将起看成一次走1米或者走k+1米,这样用个记忆化搜索加前缀和就可以解决这个问题了。
include
#include
#include
using namespace std;
const int maxn = 1010;
const int INF = 1<<20;
const int mod = 1e9+7;
int q,k;
long long res[100005];
long long ssum[100005];
long long func(int i)
{
if(res[i]!=0){
return res[i];
}
else{
if(i
就是在给的数中找多段连续的上升子序列,最低点买入,最高点卖出。
#include
using namespace std;
int main(){
long long T,n;
cin>>T;
while(T--){
cin>>n;
long long a[n];
for(long long i=0;i>a[i];
long long value=0,count=0,temp=a[0];
for(long long i=0;i0){
count+=2;
}
temp=a[i];
}
}
if(a[n-1]>temp){
value+=a[n-1]-temp;
count+=2;
}
cout<
先考虑当方格没有破坏的时候,可以很容易得出n为偶有2*n辆,n为奇数时2*(n-1)+1辆(可以证明出来,或者找规律),接下来就是考虑被破坏的地方,然后减去相应的车辆,这个是有规律的。要小心的就是奇数时,中心十字架的位置。我写的比较繁琐,求个大佬的简单思路。
#include
using namespace std;
int main(){
int n,m;
while(cin>>n>>m){
bool h[n+1];//记录行
bool l[n+1];//记录列
memset(h,0,sizeof(h));
memset(l,0,sizeof(l));
int x,y;
if(n%2==0){
int st=2*n;
for(int i=0;i>x>>y;
if(h[x]==0&&l[y]==0){
st-=2;
h[x]=1,l[y]=1;
}
if(h[x]!=0&&l[y]==0){
st-=1;
l[y]=1;
}
if(h[x]==0&&l[y]!=0){
st-=1;
h[x]=1;
}
}
cout<>x>>y;
if(x==(n+1)/2||y==(n+1)/2){
if(x==(n+1)/2&&y!=(n+1)/2){
if(l[y]==0){
st-=1;
}
}
else if(y==(n+1)/2&&x!=(n+1)/2){
if(h[x]==0){
st-=1;
}
}
h[x]=1,l[y]=1;
}
else
{
if(h[x]==0&&l[y]==0){
st-=2;
h[x]=1,l[y]=1;
}
if(h[x]!=0&&l[y]==0){
st-=1;
l[y]=1;
}
if(h[x]==0&&l[y]!=0){
st-=1;
h[x]=1;
}
}
}
if(l[(n+1)/2]==1&&h[(n+1)/2]==1)
cout<
完结,撒花!!!!!!