Codeforces Round 1051 Div.2 补题
无语 还得练
原题连接
参考dalao的题解
D1
摸出了样例中单调下降序列长度>=3时就不能算入,但是之后不知道该怎么处理。
题解中转化为:合法序列的单调下降序列长度<3,使用记录LIS序列中的值进行计数类dp
const int N=310,W=1e4+10,mod=1e9+7,inf=1e15;
int dp[2][N][N];//遍历n层 dp[x][y] 下降子序列:x,y x>=y
// int qpow(int a,int b){
// int ret=1;
// while (b)
// {
// if(b&1)ret*=a,ret%=mod;
// a*=a,a%=mod;
// b>>=1;
// }
// return ret;
// } //一开始以为组合问题
void solve()
{memset(dp,0,sizeof dp);int n;cin>>n;vector<int>a(n+1);forr(i,1,n)cin>>a[i];dp[0][0][0]=1;//没有下降子序列 初始情况forr(i,1,n){int rw=i&1;memset(dp[rw],0,sizeof dp[rw]);//记得把上一行清空forr(x,0,n){forr(y,0,x){dp[rw][x][y]+=dp[rw^1][x][y],dp[rw][x][y]%=mod;//不转移int nx=x,ny=y;if(a[i]>=x)nx=a[i],ny=y;else if(a[i]>=y)nx=x,ny=a[i];else continue;dp[rw][nx][ny]+=dp[rw^1][x][y],dp[rw][nx][ny]%=mod;//转移到别的地方}}}int ans=0;forr(i,0,n){forr(j,0,n)ans+=dp[n&1][i][j],ans%=mod;}cout<<ans<<endl;
}
D2
优化
- D1中转移:
x≤a[i]:dp[x][y]→dp[a[i]][y]x>a[i]≥y:dp[x][y]→dp[a[i]][y]x\leq a[i]:dp[x][y]\rightarrow dp[a[i]][y] \\ x>a[i]\geq y:dp[x][y]\rightarrow dp[a[i]][y]x≤a[i]:dp[x][y]→dp[a[i]][y]x>a[i]≥y:dp[x][y]→dp[a[i]][y] - 那么dp[a[i]][y]=∑x=0a[i]dp[x][y],dp[x][a[i]]=∑y=0a[i]dp[x][y]dp[a[i]][y]=\sum\limits_{x=0}^{a[i]} dp[x][y],dp[x][a[i]]=\sum\limits_{y=0}^{a[i]} dp[x][y]dp[a[i]][y]=x=0∑a[i]dp[x][y],dp[x][a[i]]=y=0∑a[i]dp[x][y]
维护区间和,用树状数组
//尝试学习中