首先最外层循环枚举的是总共的得分次数,包括x+1,x,x/2,那么n-i就是没得分的情况。
里层循环j代表得x/2的情况,要么没有,要么最多1次,如果两次会变成x那么之前的循环已经枚举过了。
lower代表的是得x+1分的下限那就是总共i的得分减去x/2也就是j的得分再减去x最多的得分次数也就是(n-m)。
upper 就代表x + 1的得分上限,因为两种音符都可以得到x+1分。
base代表都得了x分的情况,为了计算最小的得分,方便后期减去重复区间。
upper - lower + 1代表i个音符得分的情况下整个区间都可以满足(最后要减去重复的区间)
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
if(m==n){
cout<<n+1<<"\n";//取0,1,2,.....,n总共n+1种
return 0;
}
long long M = 10000000;
int ans = 1;//全都不取为1种
int lst = 0;//总共有i个音符得分,最小的分数
for(int i=1;i<=n;i++){//i为得分的次数,那么n-i就是得分为0的次数
for(int j=1;j>=0;j--){//统计x/2出现的次数,最多1次。
int lower = max(0, i - (n - m) - j);//得分下限
int upper = i - j;//得分上限
int base = (2 * i - j) * M /(2 * n);//假设都得x分(为了计算最小的得分情况)
ans += upper - lower + 1;//代表这个区间都可以取到
if(lower + base <= lst){//消除重复区间
ans -= lst - (lower + base) + 1;
lst = base + upper;
}
}
}
cout<<ans<<"\n";
return 0;
}