好没意思(((
建议kickstart更名为div4,当然我只是建议
第一次打,以后不会再打了
A:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N = 3e5+5;
int t,n,a[100005],b,cas;
int main(){
ios::sync_with_stdio(false);
cin>>t;
while (t--){
cas++;
cin>>n>>b;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);
int now=0;
while (now<n&&b>=a[now+1]){
b-=a[now+1];
now++;
}
cout<<"Case #"<<cas<<": ";
cout<<now<<endl;
}
}
B:
dp[i][j]表示前i堆物品最多选j个的答案,枚举下一堆选多少即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N = 3e5+5;
int t,n,k,p;
int v[55][55];
int dp[55][1555],f[55][55];
int main(){
ios::sync_with_stdio(false);
cin>>t;
int cas=0;
while (t--){
cas++;
memset(dp,0, sizeof(dp));
cin>>n>>k>>p;
for(int i=1;i<=n;i++)for(int j=1;j<=k;j++)cin>>v[i][j],f[i][j]=v[i][j]+f[i][j-1];
for(int i=1;i<=n;i++){
for(int j=p;j>=0;j--){
for(int s=0;s<=j&&s<=k;s++){
dp[i][j]=max(dp[i][j],dp[i-1][j-s]+f[i][s]);
}
}
}
cout<<"Case #"<<cas<<": ";
cout<<dp[n][p]<<endl;
}
}
C:
二分
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N = 1e5+5;
int t,n,k,a[N];
bool can(int x){
int ned = 0;
for(int i=2;i<=n;i++){
int dis = a[i]-a[i-1];
int c = dis/x;
if(dis%x==0)c--;
ned+=c;
}
return ned<=k;
}
int main(){
ios::sync_with_stdio(false);
cin>>t;
int cas = 0;
while (t--){
cas++;
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
int l=1,r=1e9;
while (l<=r){
int mid = l+r>>1;
if(can(mid)){
r=mid-1;
}else{
l=mid+1;
}
}
cout<<"Case #"<<cas<<": ";
cout<<l<<endl;
}
}
D:
想了几分钟,首先想到是否可以贪心选,就是每次都找一堆公共前缀最长的串拿出来
很容易发现这个贪心是对的
然后就是傻逼trie树了,时间复杂度也很好求
顺便这评测姬真强大,我memset竟然都没事。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5;
int t,n,k;
string s[N];
int tree[5000000][26],pre[5000000],tot;
int sum[5000000];
int cas = 0;
void insert(string str){
int root = 0;
for(int i=0;i<str.length();i++){
int id = str[i]-'A';
if(!tree[root][id])
tree[root][id]=++tot;
sum[tree[root][id]]++;
pre[tree[root][id]]=root;
root = tree[root][id];
}
}
void slove(){
cas++;
int ans = 0;
for(int i=tot;i>=1;i--){
while (sum[i]>=k){
int dep=0;
int now = i;
while (now!=0){
sum[now]-=k;
dep++;
now=pre[now];
}
ans+=dep;
}
}
cout<<"Case #"<<cas<<": ";
cout<<ans<<endl;
}
int main(){
ios::sync_with_stdio(false);
cin>>t;
while (t--){
cin>>n>>k;// n/k
for(int i=1;i<=n;i++)cin>>s[i],insert(s[i]);
slove();
memset(pre,0, sizeof(pre));
memset(sum,0, sizeof(sum));
// for(int i=0;i<=tot;i++)pre[tot]=sum[tot]=0;
tot=0;
memset(tree,0, sizeof(tree));
}
}