A 题
水题不解释,主要是用vector容器就行了,不然开数组还稍微麻烦一点。
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
typedef pair<int, int> pir;
struct ss {
int ab, sc;
}p[200];
int main()
{
int n, m, k;
cin >> n >> m >> k;
vector<int >v[105];
up(i, 0, n)
{
cin >> p[i].ab;
}
up(i, 0, n)
{
cin >> p[i].sc;
v[p[i].sc].push_back(p[i].ab);
}
up(i, 0, n)
{
sort(v[i].begin(), v[i].end(),greater<int >());
}
int kk[105];
int ans = 0;
up(i, 0, k)
{
cin >> kk[i];
if (v[p[kk[i]-1].sc].front() != p[kk[i]-1].ab)
ans++;
}
cout << ans;
return 0;
}
B题 代码略 写的很丑。。
主要就是暴力求解两两的和。题目告诉我们糖果数量unique,那么如果出现两个9,必然就是不同的四个数字组成的,所以开数组储存所有
两两的和,然后upper-lower_bound就得到答案。(其实感觉二分查答案应该算很快的方法了把)
c题水题,模拟题目。
代码略。。也是写的很丑。
主要在于这里数据给的小,所以我直接暴力for(i,0,t)t就是时间。
然后对于每一个时间,让在队伍里面的test++,知道有一个== ai了,出队,然后让下一个入队。
在每一个时刻还需要做的事情,如果有一个test==d了,那么ans++。最后ans就是答案。
F题,求子串的代价。``
代码很简单,但是思想还是重要的。
这道理类似于白皮书上,用线段树来维护dp得题目。
对于每一个区间,找端点值在(l,r)种中的,然后更新dp。
这道题目类似,但是是关于字符串的,也是关于前缀的一道题。
我们思考可以得出状态转移方程
dp[i]=min(dp[i]+a,dp[L]+b|i-R>L)
也就是说,dp能从,以i结尾的某个前缀的前一个字母+b转移过来。
所以我们首先预处理前缀,对于任意的i,从0-i来寻找,找si==sj,然后开个二维数组来保存任意j,i的前缀长度就好了。
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
typedef pair<int, int> pir;
string s;
int cnt[5500][5500];
int dp[5500];
int main()
{
int n, a, b;
cin >> n >> a >> b;
cin >> s;
up(i, 1, n)
{
up(j, 0, i)
{
if (s[i] == s[j])
{
cnt[i][j] = 1;
if (j)cnt[i][j] += cnt[i - 1][j - 1];
}
}
}//预处理前缀,以前一直以为这样暴力是解决不了的。。今天终于有用处了
dp[0] = a;
up(i, 0, n)
{
if (i)dp[i] = dp[i - 1] + a;
up(j, 0, i)
{
if (cnt[i][j])
{
if (i - cnt[i][j] + 1 > j)//注意!例如aaa这样的,可能重叠
{
dp[i] = min(dp[i], dp[i - cnt[i][j]] + b);
}//状态转移方程
}
}
}
cout << dp[n - 1] << endl;
return 0;
}