• 51NOD 1296-dp


    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1296

    题意就是一个 1--n 的序列,然后给你一些数,要再这些位置比旁边大,另一些数,这些位置要比旁边的小。。

    题意就是这样,之前做的题拿出来复习。。

    dp思路是 dp[i][j]  表示 前i个数最后一位是j是什么的时候有多少可行方案(是不是有点像数位dp的思路。。。)

    做一个标记来标记每一位和前一位的大小关系。

    那么分三种情况考虑一下:

    第i位一是个普通位  ,那么dp[i][j]就是dp[i-1][1~(i-1)]所有的答案和,为什么呢,因为可以看做把前面的每一种安排比j大的都加1就好了。。这样也不影响原来的合法性

    第i位 要比前一位低,那么明显不能都加1 了,因为不一定满足第i位合法了,所以其实保证第i-1位大于等于j,也就是dp[i-1][j~(i-1)]所有答案的和,

    第i位 要比前一位高, 同理,就是dp[i-1][1~j-1]所有答案的和,

    由于上面的转移方法,所以我们再加一个辅助的前缀和数组就可以了。

    代码如下:

    #include <iostream>
    #include <vector>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    int dp[5001][5001];
    int sum[5001];
    int a[5001];
    int b[5001];
    int n,na,nb;
    int ans;
    const int mo=1e9+7;
    
    void DP(){
        ans=0;
        memset(dp,0,sizeof(dp));
        dp[1][1]=1;
        sum[1]=1;
        for(int i=2;i<=n;i++){
            for(int j=1;j<=i;j++){
                if(a[i]==1){
                    dp[i][j]=sum[j-1];
                }
                else if(a[i]==-1){
                    dp[i][j]=(sum[i-1]-sum[j-1]+mo)%mo;
                }
                else{
                    dp[i][j]=sum[i-1];
                }
            }
            for(int j=1;j<=i;j++){
                sum[j]=((long long)sum[j-1]+dp[i][j])%mo;
            }
        }
        for(int i=1;i<=n;i++){
            ans=(ans+dp[n][i])%mo;
        }
        cout<<ans%mo<<endl;
    }
    int main()
    {
        while(cin>>n>>na>>nb){
            int x;
            for(int i=0;i<na;i++){
                scanf("%d",&x);
                ++x;
                a[x]=1;
                a[x+1]=-1;
            }
            memset(b,0,sizeof(b));
            for(int i=0;i<nb;i++){
                scanf("%d",&x);
                ++x;
                a[x]=-1;
                a[x+1]=1;
            }
            DP();
        }
        return 0;
    }
    



  • 相关阅读:
    通信原理
    java实现聊天室的简单实现
    计算机网络笔记——第四章、网络层
    泛型高级之通配符
    看文档总结
    HashSet源码解析
    HashTable源码解析
    计算机网络笔记——第三章、数据链路层
    Collection集合的功能
    第六章 应用层
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672571.html
Copyright © 2020-2023  润新知