A. Set of Strings

  题意:能否把一个字符串划分为n段,且每段第一个字母都不相同?

  思路:判断字符串中出现的字符种数,然后划分即可。

 #include<iostream>
#include<set>
#include<cstdio>
#include<cstring>
using namespace std;
char s[];
set<char>st;
int main()
{
int n;
scanf("%d%s", &n,s);
int len = strlen(s);
for (int i = ; i < len; i++)
{
if (!st.count(s[i]))st.insert(s[i]);
}
if (st.size() < n) printf("NO\n");
else
{
st.clear();
printf("YES\n");
int cur = ;
while (n--)
{
st.insert(s[cur]);
while (cur<len&&st.count(s[cur]))
{
printf("%c", s[cur++]);
}
if (n == )
{
while(cur<len) printf("%c", s[cur++]);
}
printf("\n");
}
}
return ;
}

B. Sea and Islands

  题意:n*n的网格里都是水,现在需要填沙造出k个陆地,两两之间有边相邻的看成一片陆地。

  思路:讨论奇偶。

 #include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n, k;
scanf("%d%d", &n, &k);
int maxs = n / * n + n % * (n + ) / ;
if (k > maxs)printf("NO\n");
else
{
printf("YES\n");
for (int i = ; i < n; i++)
{
int st;
if (i % ==) st = ;
else st = ;
for (int j=; j < n; j++)
{
if ((j - st) % == &&k>) printf("L"),k--;
else printf("S");
}
printf("\n");
}
}
return ;
}

C. Writing Code

  题意:有n个程序员,现在需要合作完成m行的代码,要求最多只有b个bug,求总方案数?

  思路:dp[i][j][k]:表示前i个程序员一起写j行代码bug数为k的方案数.采用滚动数组优化。

 #include<iostream>
#include<cstdio>
using namespace std;
const int maxn = ;
const int maxm = ;
const int maxb = ;
int dp[][maxm][maxb];//[i][j][k]表示前i个程序员一起写j行代码bug数为k的方案数
int bugs[maxn];
int main()
{
int n, m, b, mod;
scanf("%d%d%d%d", &n, &m, &b, &mod);
for (int i = ; i <= n; i++) scanf("%d", bugs + i);
dp[][][] = dp[][][] = ;
int pre, now;
for (int i = ; i <= n; i++)
{
for (int j = ; j <= m; j++)
{
for (int k =; k <= b; k++)
{
pre = ((i - ) & ),now=(i&);
if (k >= bugs[i]) dp[now][j][k] = (dp[pre][j][k] + dp[now][j - ][k - bugs[i]]) % mod;
else dp[now][j][k] = dp[pre][j][k];
}
}
}
int ans = ;
for (int i = ; i <= b; i++) ans = (ans + dp[now][m][i]) % mod;
printf("%d\n",ans);
return ;
}

D. Destroying Roads

  题意:有n个点,m条无向边。在保证s1到t1不超过l1小时、s2到t2不超过l2小时(每走一条边花费1小时)的情况下,求最多可以删去多少条边?

  思路:求出每两点之间的最短距离,然后2层循环枚举重复的路径。

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = ;
struct edge
{
int next, to;
edge(int tt=,int nn=):to(tt),next(nn){}
};
edge Edge[maxn*maxn];
int Head[maxn], totedge;
void addedge(int from, int to)
{
Edge[totedge] = edge(to, Head[from]);
Head[from] = totedge++;
Edge[totedge] = edge(from, Head[to]);
Head[to] = totedge++;
}
int dis[maxn][maxn];
bool vis[maxn];
const int INF = 0x3f3f3f3f;
int n, m;
void SPFA(int st)
{
for (int i = ; i <= n; i++) dis[st][i] = INF;
dis[st][st] = ;
vis[st] = true;
queue<int>q;
q.push(st);
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for (int i = Head[u]; i != -; i = Edge[i].next)
{
int v = Edge[i].to;
if (dis[st][v] > dis[st][u] + )
{
dis[st][v] = dis[st][u] + ;
if (!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
memset(Head, -, sizeof(Head));
totedge = ;
for (int i = ; i <= m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
addedge(u, v);
}
int s1, d1, l1, s2, d2, l2;
scanf("%d%d%d%d%d%d", &s1, &d1, &l1, &s2, &d2, &l2);
for (int i = ; i <= n; i++) SPFA(i);
if (dis[s1][d1] > l1 || dis[s2][d2] > l2) printf("-1\n");
else
{
int minnum = dis[s1][d1] + dis[s2][d2];
for (int i = ; i <= n; i++)
{
for (int j = ; j <= i; j++)
{
if (dis[s1][i] + dis[i][j] + dis[j][d1] <= l1 && dis[s2][i] + dis[i][j] + dis[j][d2] <= l2)
{
minnum = min(minnum, dis[s1][i] + dis[i][j] + dis[j][d1] + dis[s2][i] + dis[j][d2]);
}
if (dis[s1][i] + dis[i][j] + dis[j][d1] <= l1 && dis[s2][j] + dis[j][i] + dis[i][d2] <= l2)
{
minnum = min(minnum, dis[s1][i] + dis[i][j] + dis[j][d1] + dis[s2][j] + dis[i][d2]);
}
if (dis[s1][j] + dis[j][i] + dis[i][d1] <= l1 && dis[s2][i] + dis[i][j] + dis[j][d2] <= l2)
{
minnum = min(minnum, dis[s1][j] + dis[j][i] + dis[i][d1] + dis[s2][i] + dis[j][d2]);
}
if (dis[s1][j] + dis[j][i] + dis[i][d1] <= l1 && dis[s2][j] + dis[j][i] + dis[i][d2] <= l2)
{
minnum = min(minnum, dis[s1][j] + dis[j][i] + dis[i][d1] + dis[s2][j] + dis[i][d2]);
}
}
}
printf("%d\n", m - minnum);
}
return ;
}

E. Remembering Strings

  题意:有n个字符串,每个字符串m位,要使得每个字符串存在一个位置i上的字符唯一(其他字符串该位上的字符与该字符串不同,称为易记字符串),你可以将某个字符串某位替换成任意字符,给出每个字符串每位替换的代价,求最小代价?

  思路:将n个字符串各自是否为易记标记为0/1,则我们可以进行状态压缩,对每个当前的状态,找到最低位的0(表示该字符串进行转换,其余高位的0无需转换),按照以下策略进行替换:如果该位唯一,则dp[i | (1 << j)] = dp[i],否则考虑2种方案:第一种方案,直接让该位字符唯一——dp[i | (1 << j)] = min(dp[i | (1 << j)], dp[i] + cost[j][k]);第二种方案,找到所有和该字符串该位字符一样的所有字符串,除去代价最大的,其他字符串进行转换——dp[i | tmp] = min(dp[i | tmp], dp[i] + sumc - maxc)。

  初始化为-1时需要考虑当前状态在此前是否已被转换到,没有则跳过;初始化为INF则不用考虑。

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
char str[][];
int cost[][];
const int maxc = << ;//最大状态数
int dp[maxc];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i < n; i++) scanf("%s", str + i);
for (int i = ; i < n; i++)
{
for (int j = ; j < m; j++) scanf("%d", &cost[i][j]);
}
int total = ( << n) - ;//最终状态为111...11,n个1表示n个字符串都为易记
memset(dp, -, sizeof(dp));
dp[] = ;
for (int i = ; i <total; i++)//枚举状态
{
if (dp[i] == -) continue;//该状态没有被转移到,跳过
int j = ;
while (((i >> j) & ) == ) j++;//找到该状态中为非易记的字符串进行状态转移
for (int k = ; k < m; k++)
{//让该字符串第k位的字符唯一
int cnt = , sumc = , maxc = , tmp = ;
for (int z = ; z < n; z++)
{
if (str[z][k] == str[j][k])
{
cnt++;
sumc += cost[z][k];//总代价
maxc = max(maxc, cost[z][k]);//最大代价
tmp |= ( << z);//所有和该字符串该位一样的字符串为易记时的状态
}
}
if (cnt == )//如果该位字符本就唯一
{
if (dp[i | ( << j)] == -)dp[i | ( << j)] = dp[i];
else dp[i | ( << j)] = min(dp[i | ( << j)], dp[i]);
}
else//否则
{
//第一种方案,直接让该位字符唯一
if (dp[i | ( << j)] == -) dp[i | ( << j)] = dp[i] + cost[j][k];
else dp[i | ( << j)] = min(dp[i | ( << j)], dp[i] + cost[j][k]);
//第二种方案,找到所有和该字符串该位字符一样的所有字符串,除去代价最大的,其他字符串进行转换
if (dp[i | tmp] == -) dp[i | tmp] = dp[i] + sumc - maxc;
else dp[i | tmp] = min(dp[i | tmp], dp[i] + sumc - maxc);
}
}
}
printf("%d\n", dp[total]);
return ;
}

Codeforces Round #302 (Div. 2)的更多相关文章

  1. 完全背包 Codeforces Round #302 (Div. 2) C Writing Code

    题目传送门 /* 题意:n个程序员,每个人每行写a[i]个bug,现在写m行,最多出现b个bug,问可能的方案有几个 完全背包:dp[i][j][k] 表示i个人,j行,k个bug dp[0][0][ ...

  2. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 /* 题意:在n^n的海洋里是否有k块陆地 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 输出完k个L后,之后全部输出S:) 5 10 的例子可以是这样的: LSLS ...

  3. 水题 Codeforces Round #302 (Div. 2) A Set of Strings

    题目传送门 /* 题意:一个字符串分割成k段,每段开头字母不相同 水题:记录每个字母出现的次数,每一次分割把首字母的次数降为0,最后一段直接全部输出 */ #include <cstdio> ...

  4. Codeforces Round #302 (Div. 1) C. Remembering Strings DP

    C. Remembering Strings Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/5 ...

  5. Codeforces Round #302 (Div. 2) D - Destroying Roads 图论,最短路

    D - Destroying Roads Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544 ...

  6. Codeforces Round #302 (Div. 2) C. Writing Code 简单dp

    C. Writing Code Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544/prob ...

  7. Codeforces Round #302 (Div. 2) B. Sea and Islands 构造

    B. Sea and Islands Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544/p ...

  8. Codeforces Round #302 (Div. 2) A. Set of Strings 水题

    A. Set of Strings Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544/pr ...

  9. Codeforces Round #302 (Div. 1) 训练

    链接: http://codeforces.com/contest/543 过程: 惨淡的只做出了A和C 题解: A 题解: 简单的一道题 我们用$dp[i][j]$表示当前考虑到前num个人(这个另 ...

  10. Codeforces Round #302 (Div. 2).C. Writing Code (dp)

    C. Writing Code time limit per test 3 seconds memory limit per test 256 megabytes input standard inp ...

随机推荐

  1. php max_execution_time执行时间问题

    php.ini 中缺省的最长执行时间是 30 秒,这是由 php.ini 中的 max_execution_time 变量指定,倘若你有一个需要颇多时间才能完成的工作,例如要发送很多电子邮件给大量收件 ...

  2. 卧槽! JavaScript JVM运行Java!!

    由于任何计算机语言都具有巨大的灵活性,软件世界变得有点疯狂.一旦你已经吸收了用这种语言编写的编译器的想法,那么它会编译还有什么可以留下来的?但是......用JavaScript编写的Java虚拟机J ...

  3. PAT001 一元多项式求导

    题目: 设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为n*xn-1.) 输入格式:以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格 ...

  4. C语言 百炼成钢27

    /* 题目63:编写C++程序完成以下功能: (1)声明一个纯虚函数类Shape(形状),其中包含来计算面积.计算周长的方法: (2)从Shape派生两个类矩形和圆形: (3)从矩形派生正方形: (4 ...

  5. 第一百五十三节,封装库--JavaScript,表单验证--备注字数验证

    封装库--JavaScript,表单验证--备注字数验证 效果图 html <div id="reg"> <h2 class="tuo"> ...

  6. Vector类与Enumeration接口

    Vector类用于保存一组对象,由于java不支持动态数组,Vector可以用于实现跟动态数组差不多的功能.如果要将一组对象存放在某种数据结构中,但是不能确定对象的个数时,Vector是一个不错的选择 ...

  7. Android 消息处理源代码分析(2)

    Android 消息处理源代码分析(1)点击打开链接 继续接着分析剩下的类文件 Looper.java public final class Looper { final MessageQueue m ...

  8. centos7 安装kvm虚拟机

    准备工作 centos7 光盘文件 物理机(>=4 Cores; >= 4GB memory; >= 40G disk size) 参考文档:KVM Virtualization i ...

  9. (转)Unity笔记之编辑器(BeginToggleGroup、BoundsField、ColorField) ...

    1. BeginToggleGroup() BeginToggleGroup函数是定义了一个控制范围,可以控制该范围中的GUI是否启用,看下演示代码: [code]csharpcode: using ...

  10. Python_selenium之处理Alert窗

    Python_selenium之处理Alert窗 一.介绍 1. 介绍如何通过switch_to方法处理网页Alert窗口 2. 然后我们自己创建一个alert弹窗进行操作 二.测试脚本 1. 测试脚 ...