dp 2016.10.23

1、Codeforces 463D Gargari and Permutations

参考:http://blog.csdn.net/qq_24451605/article/details/48630899

题意:

给出 k 个序列,每个序列都由 1...n 组成,求这 k 个序列的最长公共子序列的长度

解题思路:

dp[i] 表示以 i 结尾的最长公共子序列的长度

cnt[i] 表示 i 出现过的次数,当 cnt[i] 等于 k 的时候判断是否进行转移

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e3 + 10;

int n, k;
int num[maxn][maxn], pos[maxn][maxn], cnt[maxn], dp[maxn];
vector<int> V;

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d %d", &n, &k);
    for (int i = 1; i <= k; ++i) {
        for (int j = 1; j <= n; ++j) {
            scanf("%d", &num[i][j]);
            pos[i][num[i][j]] = j;
        }
    }
    memset(dp, 0, sizeof(dp));
    memset(cnt, 0, sizeof(cnt));
    V.push_back(0);
    for (int i = 1; i <= k; ++i) {
        for (int j = 1; j <= n; ++j) {
            ++cnt[num[i][j]];
            if (cnt[num[i][j]] == k) {
                for (int t = 0; t < (int)V.size(); ++t) {
                    bool flag = true;
                    for (int v = 1; v <= k; ++v) {
                        if (pos[v][V[t]] > pos[v][num[i][j]]) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        dp[num[i][j]] = max(dp[num[i][j]], dp[V[t]]+1);
                    }
                }
                V.push_back(num[i][j]);
            }
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        ans = max(ans, dp[i]);
    }
    printf("%d\n", ans);
    return 0;
}


2、Codeforces 666A Reberland Linguistics

参考:http://www.cnblogs.com/qhy285571052/p/d51cf80b94c4caf676fa33aef57096e0.html

http://www.voidcn.com/blog/wlx65003/article/p-6046070.html

题意:

一个字符串由长度大于 4 的根和长度为 2 或 3 的若干个后缀组成,两个相邻的后缀不能一样,问有多少种后缀,并按字典序输出

解题思路:

dp[i] 表示第 i 个位置到字符串结束能否划分成合法后缀

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e4 + 10;

string s;
set<string> Set;
int dp[maxn];

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    cin >> s;
    s = s.substr(5);
    int len = s.length();
    string t;
    dp[len] = 1;
    for (int i = len-1; i >= 0; --i) {
        for (int j = 2; j <= 3; ++j) {
            t = s.substr(i, j);
            if (((int)s.find(t, i+j) != i+j || dp[i+5]) && dp[i+j]) {
                Set.insert(t);
                dp[i] = 1;
            }
        }
    }
    printf("%d\n", Set.size());
    for (set<string>::iterator itr = Set.begin(); itr != Set.end(); ++itr) {
        cout << *itr << endl;
    }
    return 0;
}

3、Codeforces 269B Greenhouse Effect

参考:http://blog.csdn.net/qq_24451605/article/details/48649147

http://www.cnblogs.com/hundundm/archive/2013/02/03/2891217.html

题意:

有 n 颗植物,种类为 m 种,种在一个无限长的实数轴上

现在可以通过改变一些植物的坐标,使得最后所有植物的种类沿 x 轴正方向为不下降序列

问最少要改变多少植物的位置

解题思路:

植物的坐标是没什么用的,因为一定是严格递增的

dp[i] 代表前 i 个植物,要保证升序的情况下最多保留的植物的个数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ll mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 5e3 + 10;

int n, m;
int s[maxn], dp[maxn];
double x;

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%d %lf", &s[i], &x);
    }
    s[++n] = m + 1;
    for (int i = 1; i <= n; ++i) {
        dp[i] = 0;
        for (int j = 1; j < i; ++j) {
            if (s[i] >= s[j]) {
                dp[i] = max(dp[i], dp[j]);
            }
        }
        ++dp[i];
    }
    printf("%d\n", n-dp[n]);
    return 0;
}


4、Codeforces 375B Maximum Submatrix 2

参考:http://blog.csdn.net/qq_24451605/article/details/48651451

题意:

给出一个 01 矩阵,行与行之间可以互换位置,问能够得到最大的全 1 矩阵的面积

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ll mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 5e3 + 10;

int n, m, ans = 0;
char num[maxn][maxn];
int dp[maxn][maxn];

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%s", num[i]+1);
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (num[i][j] == '1') {
                dp[j][i] = dp[j-1][i] + 1;
            }
        }
    }
    for (int j = 1; j <= m; ++j) {
        sort(dp[j] + 1, dp[j] + 1 + n);
        for (int i = n; i >= 1; --i) {
            ans = max(ans, dp[j][i] * (n - i + 1));
        }
    }
    printf("%d\n", ans);
    return 0;
}

5、Codeforces 577B Modulo Sum

参考:http://codeforces.com/contest/577/standings

解题思路:

用 sum[i] 表示前缀和,当 n > m 时,根据鸽巢原理,sum[i] % m 的值必然会出现相等的情况,假如相等的为 sum[low] % mod 和 sum[high] % mod,那么区间 (low, high] 的和必然是 m 的倍数

当 n ≤ m,用 dp[i][j] 表示区间 [l, i] 是否存在某些数的和对 m 取模为 j,dp[i][j] = 1 表示存在

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ll mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e3 + 10;

int n, m;
int a[1000010], dp[maxn][maxn];

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    if (n > m) {
        printf("YES\n");
    } else {
        for (int i = 1; i <= n; ++i) {
            dp[i][a[i] % m] = 1;
            for (int j = 0; j <= m-1; ++j) {
                dp[i][(j + (a[i] % m)) % m] |= dp[i-1][j];
                dp[i][j] |= dp[i-1][j];
            }
        }
        if (dp[n][0]) {
            printf("YES\n");
        } else {
            printf("NO\n");
        }
    }
    return 0;
}


select * from ( SELECT P.PATIENT_ID, P.VISIT_ID, PM.NAME, PM.SEX, P.ADMISSION_DATE_TIME, ( SELECT TOP 1 DP.DEPT_NAME FROM DEPT_DICT DP WHERE DP.DEPT_CODE = P.DEPT_ADMISSION_TO ) AS DEPT_ADM, P.DISCHARGE_DATE_TIME, ( SELECT TOP 1 DP.DEPT_NAME FROM DEPT_DICT DP WHERE DP.DEPT_CODE = P.DEPT_DISCHARGE_FROM ) AS DEPT_DIS, DATEDIFF( DAY, P.ADMISSION_DATE_TIME, P.DISCHARGE_DATE_TIME ) AS INPAT_DAYS, P.DOCTOR_IN_CHARGE --datediff(day, P.ADMISSION_DATE_TIME,P.DISCHARGE_DATE_TIME) as zyts FROM PAT_VISIT P INNER JOIN PAT_MASTER_INDEX PM ON PM.PATIENT_ID = P.PATIENT_ID WHERE select * from ( SELECT P.PATIENT_ID, P.VISIT_ID, PM.NAME, PM.SEX, P.ADMISSION_DATE_TIME, ( SELECT TOP 1 DP.DEPT_NAME FROM DEPT_DICT DP WHERE DP.DEPT_CODE = P.DEPT_ADMISSION_TO ) AS DEPT_ADM, P.DISCHARGE_DATE_TIME, ( SELECT TOP 1 DP.DEPT_NAME FROM DEPT_DICT DP WHERE DP.DEPT_CODE = P.DEPT_DISCHARGE_FROM ) AS DEPT_DIS, DATEDIFF( DAY, P.ADMISSION_DATE_TIME, P.DISCHARGE_DATE_TIME ) AS INPAT_DAYS, P.DOCTOR_IN_CHARGE --datediff(day, P.ADMISSION_DATE_TIME,P.DISCHARGE_DATE_TIME) as zyts FROM PAT_VISIT P INNER JOIN PAT_MASTER_INDEX PM ON PM.PATIENT_ID = P.PATIENT_ID WHERE P.DISCHARGE_DATE_TIME >= '2016-01-01' AND P.DISCHARGE_DATE_TIME < = '2023-07-10' AND DATEDIFF( DAY,P.ADMISSION_DATE_TIME, P.DISCHARGE_DATE_TIME ) >= 30 ) t order by inpat_days desc P.DISCHARGE_DATE_TIME >= '2016-01-01' AND P.DISCHARGE_DATE_TIME < = '2023-07-10' AND DATEDIFF( DAY,P.ADMISSION_DATE_TIME, P.DISCHARGE_DATE_TIME ) >= 30 ) t order by inpat_days desc 帮我把这段sql优化一下
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值