组合数 (选定思想) dp cf1000D - Yet Another Problem On a Subsequence

http://codeforces.com/problemset/problem/1000/D

参考自:https://www.cnblogs.com/hua-dong/p/9238795.html

题意:给定序列,问有多少子序列(不一定连续),满足可以划分为若干个组,给个组的第一个等于区间长度-1;

思路:关键就在于区间的开头,由此我们从后往前考虑,dp[ i ] 表示以 i 开头,满足题意的数量,sum[ i ] 表示 i 及以后所有的可能情况。

对于 i ,可选的区间为 [ i , j ] , j 的范围是 i+a[ i ] ~ n,再利用选定的思想,这一段区间的可能情况就有 C (  a[ i ] -1 , j - i -1 ) ,接着,再乘上(1+sum[ j +1 ]),

这就是对乘法思想的利用,而这个 1 代表只选前面一个段的情况,通过不断的累加就得到 dp[ i ],再累加就得到 sum[ i ]。

 

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int Mod=998244353;
const int maxn=1010;
int a[maxn],dp[maxn],sum[maxn];
int c[maxn][maxn],ans;
int main()
{
    int N,i,j;
    scanf("%d",&N);
    for(i=0;i<=N;i++) c[i][0]=1,c[i][1]=i,c[i][i]=1;
    for(i=1;i<=N;i++)
     for(j=1;j<=N;j++)
       c[i][j]=(c[i-1][j]+c[i-1][j-1])%Mod;
    for(i=1;i<=N;i++) scanf("%d",&a[i]); 
    for(i=N;i>=1;i--){
        if(a[i]>0&&i+a[i]<=N){
            for(j=i+a[i];j<=N;j++){
                (dp[i]+=(ll)c[j-i-1][a[i]-1]*(1+sum[j+1])%Mod)%=Mod;  //这里的1是指只有一个段的情况
                printf("%d %d \n", c[j-i-1][a[i]-1],(1+sum[j+1]));
            }
        }
        sum[i]=(sum[i+1]+dp[i])%Mod;
        // printf("%d\n", sum[i]);
    }
    printf("%d\n",sum[4]);
    return 0;
}









// #include <iostream>
// #include <cstdio>
// #include <cstdlib>
// #include <cstring>
// #include <cmath>
// #define qwq(i,j,k)      for(int i=j; i<k; ++i)
// #define qeq(i,j,k)      for(int i=j; i<=k; ++i)
// #define mem(a,b)        memset(a, b, sizeof(a))
// using namespace std;
// typedef long long ll;
// const int mx = 1e5+5;
// const int maxn = 3e3+5;
// const int inf= 0x3f3f3f3f;
// // const ll mod = 1e9+7;
// const ll INF = 1e18+100;
// int n, m;
// int cas, tol, T;

// ll C[maxn][maxn];
// ll fac[mx]; //i!
// ll inv[mx]; //i!在取模mod的情况下的逆元

// // ll fpow(ll a, ll b) {
// //     ll ans = 1;
// //     while(b) {
// //         if(b & 1)
// //             ans = ans * a % mod;
// //         a = a * a % mod;
// //         b >>= 1;
// //     }
// //     return ans;
// // }

// const ll mod=998244353;
// void handle() {
// //    fac[0] = 1;
// //    for(int i=1; i<=mx; ++i) {
// //        fac[i] = fac[i-1]*i%mod;    //阶乘的表
// //    }
// //    inv[mx] = fpow(fac[mx], mod-2);
// //    for(int i=mx-1; i>=1; --i) {
// //        inv[i] = inv[i+1] * (i+1) % mod;
// //    }
//     C[0][0] = 1;
//     C[1][0] = C[1][1] = 1;
//     for(int i=2; i<maxn; ++i) {
//         for(int j=0; j<=i; ++j) {
//             C[i][j] = j==0 ? 1 : (C[i-1][j]%mod+C[i-1][j-1]%mod)%mod;
//         }
//     }
// }

// ll a[maxn];
// ll b[maxn];
// ll ans;

// int main() {
//     //打表O(N^2)   n 1e3左右
//     handle();
//     // for(int i=1; i<=10; ++i) {
//     //     for(int j=0; j<=i; ++j) {
//     //         printf("C[%d][%d] = %lld\n", i, j, C[i][j]);
//     //     }
//     // }
//     ans=0;
//     scanf("%d",&n);
//     for(int i=1; i<=n; i++){
//         cin>>a[i];
//     }
//     for(int i=1; i<=n; i++){
//         if(a[i]>0 && a[i]+i<=n){
//             b[i] = C[n-i][ a[i] ];
//         }
//     }
//     for(int i=n-1; i>=1; i--){
//         if(b[i]!=0){
//             ll sum=0;
//             for(int j=n-1; j>=i+a[i]+1; j--){
//                 // if(a[j]>0 && a[j]+j<=n){
//                     b[i] += b[j];

//                 // }
//               // if(i==4) printf("b[4]=%lld\n", b[i]);
//             }
//             // b[i] = (b[i]%mod + b[ i+a[i]+1 ]%mod)%mod;
//             ans = (ans+b[i])%mod;
//         }   
//     }
//     printf("%d\n", b[2]);
//     cout<<ans<<endl;

//     return 0;
// }

 

转载于:https://www.cnblogs.com/-Zzz-/p/11427423.html

内容概要:本文详细介绍了施耐德M580系列PLC的存储结构、系统硬件架构、上电写入程序及CPU冗余特性。在存储结构方面,涵盖拓扑寻址、Device DDT远程寻址以及寄存器寻址三种方式,详细解释了不同类型的寻址方法及其应用场景。系统硬件架构部分,阐述了最小系统的构建要素,包括CPU、机架和模块的选择与配置,并介绍了常见的系统拓扑结构,如简单的机架间拓扑和远程子站以太网菊花链等。上电写入程序环节,说明了通过USB和以太网两种接口进行程序下载的具体步骤,特别是针对初次下载时IP地址的设置方法。最后,CPU冗余部分重点描述了热备功能的实现机制,包括IP通讯地址配置和热备拓扑结构。 适合人群:从事工业自动化领域工作的技术人员,特别是对PLC编程及系统集成有一定了解的工程师。 使用场景及目标:①帮助工程师理解施耐德M580系列PLC的寻址机制,以便更好地进行模块配置和编程;②指导工程师完成最小系统的搭建,优化系统拓扑结构的设计;③提供详细的上电写入程序指南,确保程序下载顺利进行;④解释CPU冗余的实现方式,提高系统的稳定性和可靠性。 其他说明:文中还涉及一些特殊模块的功能介绍,如定时器事件和Modbus串口通讯模块,这些内容有助于用户深入了解M580系列PLC的高级应用。此外,附录部分提供了远程子站和热备冗余系统的实物图片,便于用户直观理解相关概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值