BestCoder Round #82 (div.1) 1002 HDU 5677 dp-类似多重背包的思想

链接:戳这里

ztr loves substring

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description

ztr love reserach substring.Today ,he has n string.Now ztr want to konw,can he take out exactly k palindrome from all substring of these n string,and thrn sum of length of these k substring is L.

for example string "yjqqaq"

this string contains plalindromes:"y","j","q","a","q","qq","qaq".

so we can choose "qq" and "qaq".

Input

The first line of input contains an positive integer T(T<=10) indicating the number of test cases.

For each test case:

First line contains these positive integer N(1<=N<=100),K(1<=K<=100),L(L<=100).

The next N line,each line contains a string only contains lowercase.Guarantee even length of string won‘t more than L.

Output

For each test,Output a line.If can output "True",else output "False".

Sample Input

3

2 3 7

yjqqaq

claris

2 2 7

popoqqq

fwwf

1 3 3

aaa

Sample Output

False

True

True

题意:

给出n个串,从这n个串中选出K个回文子串,使得选出的K个回文子串的长度总和为L,满足条件输出True ,否则False

思路:

处理出长度为i的回文子串的个数(1<=i<=L)  num[i]

设置dp状态:dp[i][j][k]  表示当前执行了i次取舍操作之后,能否达到选取j个回文子串,长度为k,能达到状态dp[i][j][k]=1,否则为0

由于每次设置的dp状态只跟上一层的有关 ,可以使用滚动数组,这样就消去了一维i

dp[2][i][j] 表示当前选了i个回文子串使得长度为j的状态能否达到,而当前的状态只需要通过上一层转移即可

那么我们再来分析怎么实现dp状态的转移

1:dp[now][0][0]=1

2:for(1<=i<=L)  枚举长度为i的回文子串去计算贡献

3:   for(1<=l<=L)  表示当前长度为l

4:      for(1<=j<=K) 表示当前的回文子串个数为j

5:     for(1<=k<=num[i])  枚举每个长度为i的回文子串选取的个数

6: k+j<=K && l+k*i<=L  边界条件

dp[now][k+j][l+k*i] | =dp[last][k][j]  当前的回文子串个数为k+j,长度为l+k*i的状态需要从上一层的回文子
      串个数为k,长度为j抑或得到

其实我现在都好不是很能理解,可能我需要磨一磨具体的多重背包的推导过程看看

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int n,K,L;
int dp[2][110][110];
int num[110];
char s[110];
bool pd(int l,int r){
    while(l<=r){
        if(s[l]==s[r]){
            l++;
            r--;
        } else return false;
    }
    return true;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&K,&L);
        mst(num,0);
        for(int i=1;i<=n;i++){
            scanf("%s",&s);
            for(int j=0;j<strlen(s);j++){
                for(int k=j;k<strlen(s);k++){
                    if(pd(j,k)) num[k-j+1]++;
                }
            }
        }
        int now=0,last=1;
        dp[now][0][0]=1;
        for(int i=1;i<=L;i++){
            swap(now,last);
            mst(dp[now],0);
            for(int l=0;l<=L;l++){
                for(int j=0;j<=K;j++){
                    for(int k=0;k<=num[i];k++){
                        if(k+j>K || l+k*i>L) continue;
                        dp[now][k+j][l+k*i]|=dp[last][j][l];
                    }
                }
            }
        }
        if(dp[now][K][L]) printf("True\n");
        else printf("False\n");
    }
    return 0;
}
时间: 2024-10-22 04:11:26

BestCoder Round #82 (div.1) 1002 HDU 5677 dp-类似多重背包的思想的相关文章

计算几何(水)BestCoder Round #50 (div.2) 1002 Run

题目传送门 1 /* 2 好吧,我不是地球人,这题只要判断正方形就行了,正三角形和正五边形和正六边形都不可能(点是整数). 3 但是,如果不是整数,那么该怎么做呢?是否就此开启计算几何专题了呢 4 */ 5 /************************************************ 6 * Author :Running_Time 7 * Created Time :2015-8-8 19:54:14 8 * File Name :B.cpp 9 ************

HDU 5671 Matrix (BestCoder Round #81 (div.2) 1002)

传送门 Matrix Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 311    Accepted Submission(s): 142 Problem Description There is a matrix M that has n rows and m columns (1≤n≤1000,1≤m≤1000).Then we

BestCoder Round #50 (div.1) 1002 Run (HDU OJ 5365) 暴力枚举+正多边形判定

题目:Click here 题意:给你n个点,有多少个正多边形(3,4,5,6). 分析:整点是不能构成正五边形和正三边形和正六边形的,所以只需暴力枚举四个点判断是否是正四边形即可. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #define power(x) ((x)*(x))

BestCoder Round #73 (div.2)(hdu 5630)

Rikka with Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 177    Accepted Submission(s): 161 Problem Description Yuta gives Rikka a chess board of size n×m. As we all know, on a chess boa

BestCoder Round #68 (div.2) 1002 tree

题意:给你一个图,每条边权值0或1,问每个点周围最近的点有多少个? 思路:并查集找权值为0的点构成的连通块. 1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<math.h> 5 #include<algorithm> 6 #define clc(a,b) memset(a,b,sizeof(a)) 7 using namespace std; 8 i

BestCoder Round #71 (div.2) (hdu 5620 菲波那切数列变形)

KK's Steel Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 350    Accepted Submission(s): 166 Problem Description Our lovely KK has a difficult mathematical problem:he has a N(1≤N≤1018) meters s

BestCoder Round #66 (div.2) 1002

GTW likes gt Accepts: 132 Submissions: 772 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) 问题描述 从前,有nn只萌萌的GT,他们分成了两组在一起玩游戏.他们会排列成一排,第ii只GT会随机得到一个能力值b_ib?i??.在第ii秒的时候,第ii只GT可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的GT. 为了使游戏更加有趣,

BestCoder Round #50 (div.2) HDU 5365 Run(简单几何)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5365 题面:(严重吐槽,看着真不舒服,还是改一下吧) Run Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 549    Accepted Submission(s): 245 Problem Description AFA is a g

HDU 5651 xiaoxin juju needs help(BestCoder Round #77 (div.1)1001)

传送门 xiaoxin juju needs help Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 861    Accepted Submission(s): 243 Problem Description As we all known, xiaoxin is a brilliant coder. He knew **palin