uva11552
2016-04-02 17:24
267 查看
做过难的dp再做这种,就能很清晰的发现状态转移过程中关键的状态量
就是第i组结束后末尾的字母
dp[i][j]表示前i组,以j结尾的最少块数
dp[i][j] 转移时要转移到全部的dp[i-1][k] 分成k等于j和k不等于j分别考虑
难得1A,水题。。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
const int INF = 111111111;
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--){
char s[1005];
int have[1005][27];
int num[1005];
int dp[1005][27];
int k,l,part;
memset(have,0,sizeof(have));
memset(num,0,sizeof(num));
memset(dp,0,sizeof(dp));
scanf("%d",&k);
scanf("%s",s);
l = strlen(s);
part = l / k;
for(int i = 1; i <= part; i++){
int start = (i - 1)*k;
for(int j = 0; j < k; j++){
if (have[i][s[start + j] - 'a'] != 1)
num[i]++;
have[i][s[start + j] - 'a'] = 1;
}
//printf("%d\n",num[i]);
}
for(int j = 0; j <= 25; j++)
dp[1][j] = have[1][j]?num[1] : INF;
for(int i = 2; i <= part; i++)
for(int j = 0; j <= 25; j++){
if (!have[i][j]){
dp[i][j] = INF;
continue;
}
dp[i][j] = INF;
for(int q = 0; q <= 25; q++){
if (q == j){
if (num[i] == 1) dp[i][j] = min(dp[i][j],dp[i - 1][q]);
else dp[i][j] = min(dp[i][j],dp[i - 1][q] + num[i]);
}
else{
if (have[i][q]) dp[i][j] = min(dp[i][j],dp[i - 1][q] + num[i] - 1);
else dp[i][j] = min(dp[i][j],dp[i - 1][q] + num[i]);
}
}
}
int ans = INF;
for(int j = 0; j <= 25; j++)
ans = min(ans,dp[part][j]);
printf("%d\n",ans);
}
return 0;
}
就是第i组结束后末尾的字母
dp[i][j]表示前i组,以j结尾的最少块数
dp[i][j] 转移时要转移到全部的dp[i-1][k] 分成k等于j和k不等于j分别考虑
难得1A,水题。。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
const int INF = 111111111;
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--){
char s[1005];
int have[1005][27];
int num[1005];
int dp[1005][27];
int k,l,part;
memset(have,0,sizeof(have));
memset(num,0,sizeof(num));
memset(dp,0,sizeof(dp));
scanf("%d",&k);
scanf("%s",s);
l = strlen(s);
part = l / k;
for(int i = 1; i <= part; i++){
int start = (i - 1)*k;
for(int j = 0; j < k; j++){
if (have[i][s[start + j] - 'a'] != 1)
num[i]++;
have[i][s[start + j] - 'a'] = 1;
}
//printf("%d\n",num[i]);
}
for(int j = 0; j <= 25; j++)
dp[1][j] = have[1][j]?num[1] : INF;
for(int i = 2; i <= part; i++)
for(int j = 0; j <= 25; j++){
if (!have[i][j]){
dp[i][j] = INF;
continue;
}
dp[i][j] = INF;
for(int q = 0; q <= 25; q++){
if (q == j){
if (num[i] == 1) dp[i][j] = min(dp[i][j],dp[i - 1][q]);
else dp[i][j] = min(dp[i][j],dp[i - 1][q] + num[i]);
}
else{
if (have[i][q]) dp[i][j] = min(dp[i][j],dp[i - 1][q] + num[i] - 1);
else dp[i][j] = min(dp[i][j],dp[i - 1][q] + num[i]);
}
}
}
int ans = INF;
for(int j = 0; j <= 25; j++)
ans = min(ans,dp[part][j]);
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- 简单的四则运算
- 数的奇偶性
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- 矩阵的乘法操作
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置