A. Cloning Toys
题意:初始时有一个原版玩具,使用一个原版玩具可以制造出一个原版玩具和一个复制玩具,使用一个复制玩具可以制造出两个复制玩具。问能否得到特定数目的原版和复制玩具。
题解:a个原版b个复制,直接判断,注意特判情况a为0时b必为1、b为1时a必为0。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<iomanip>
#define maxn 300050
#define maxm 1000050
#define INF 0x3f3f3f3f
#define eps 1e-8
const double pi=acos(-1.0);
using namespace std;
typedef long long ll;
typedef long double ld;
int a,b;
int main()
{
scanf("%d%d",&a,&b);
if(b==0||(a==0&&b!=1))
{
printf("No\n");
return 0;
}
if(b==1&&a!=0)
{
printf("No\n");
return 0;
}
a-=(b-1);
if(a<0||a%2==1)printf("No\n");
else printf("Yes\n");
return 0;
}
B. Magic Forest
题意:在1-n的范围内找三元组(a,b,c)要求为三角形的三边长且三个数的异或值为0,求满足条件的三元组的个数。
题解:根据异或的性质,a^b^c=0即a^b=c,O(n^2)枚举即可解决。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<iomanip>
#define maxn 300050
#define maxm 1000050
#define INF 0x3f3f3f3f
#define eps 1e-8
const double pi=acos(-1.0);
using namespace std;
typedef long long ll;
typedef long double ld;
int n;
int main()
{
scanf("%d",&n);
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
int t=i^j;
if(t>=j&&t<=n&&t<i+j&&t>j-i)
ans++;
}
}
printf("%d\n",ans);
return 0;
}
C. Cave Painting
题意:给出n和k,判断n除以1-k中每一个数的余数是否各不相同。
题解:n除以1的余数必然为0,那么要满足题目的条件,n除以2的余数只能为1,依此类推,n除以i的余数只能为i-1。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<iomanip>
#define maxn 300050
#define maxm 1000050
#define INF 0x3f3f3f3f
#define eps 1e-8
const double pi=acos(-1.0);
using namespace std;
typedef long long ll;
typedef long double ld;
ll a,b;
int main()
{
scanf("%I64d%I64d",&a,&b);
for(ll i=2;i<=b;i++)
{
if(a%i!=i-1)
{
printf("NO\n");
return 0;
}
}
printf("YES\n");
return 0;
}
D. Robot Vacuum Cleaner
题意:给定一系列只由s和h组成的字符串,求一个字符串的排列使得总串中子序列sh的数目最多。
题解:贪心,将字符串按照s所占比重从大到小排列即可。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<iomanip>
#define maxn 100050
#define maxm 1000050
#define INF 0x3f3f3f3f
#define eps 1e-8
const double pi=acos(-1.0);
using namespace std;
typedef long long ll;
typedef long double ld;
int n;
struct node
{
string s;
double t;
}e[maxn];
bool cmp(node a,node b)
{
return a.t>b.t;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>e[i].s;
int num=e[i].s.length();
int a=0;
for(int j=0;j<num;j++)
{
if(e[i].s[j]=='s')a++;
e[i].t=1.0*a/num;
}
}
sort(e,e+n,cmp);
int num=0,p;
ll ans=0;
for(int i=0;i<n;i++)
{
p=e[i].s.length();
for(int j=0;j<p;j++)
{
if(e[i].s[j]=='s')
num++;
else ans+=num;
}
}
printf("%I64d\n",ans);
return 0;
}
E. Birds
题意:n棵树上各有ci只鸟,现在从第1棵树开始,在第i棵树上每捉一只鸟需要花费vi法力值。不论在哪棵树上,每捉一只鸟法力值上限会增加b。每换一棵树法力值会增加x,初始时法力值及其上限均为w。求最多能捉到的鸟的数目。
题解:这是一个容量不定的多重背包。dp的第一维显然是树的数目,但给出的法力值较大,不适合作为第二维。这里第二维为捉住的鸟数,dp[i][j]为走过i棵树抓了j只鸟剩下的最大法力值,最终只需要找出dp[i]中值存在的最大j值即可。状态转移方程为:
dp[i][j]=max(dp[i][j],dp[i-1][j-k]-k*v[i])
此外每一次枚举完鸟的数目以后需要增加法力值以及更新容量。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<iomanip>
#define maxn 1050
#define INF 0x3f3f3f3f
#define eps 1e-8
const double pi=acos(-1.0);
using namespace std;
typedef long long ll;
typedef long double ld;
ll n,w,b,x;
ll c[maxn],v[maxn];
ll dp[maxn][maxn*10];
ll Max(ll a,ll b){return a>b?a:b;}
ll Min(ll a,ll b){return a<b?a:b;}
int main()
{
scanf("%I64d%I64d%I64d%I64d",&n,&w,&b,&x);
for(int i=1;i<=n;i++)scanf("%I64d",&c[i]);
for(int i=1;i<=n;i++)scanf("%I64d",&v[i]);
memset(dp,-1,sizeof(dp));
dp[0][0]=w;
ll sum=0;
for(int i=1;i<=n;i++)
{
sum+=c[i];
ll cnt=w;
for(int j=0;j<=sum;j++)
{
for(int k=0;k<=c[i];k++)
{
if(k>j)break;
if(dp[i-1][j-k]==-1)continue;
if(dp[i-1][j-k]<k*v[i])continue;
dp[i][j]=Max(dp[i][j],dp[i-1][j-k]-k*v[i]);
}
if(dp[i][j]!=-1)dp[i][j]=Min(dp[i][j]+x,cnt);
cnt+=b;
}
}
for(ll i=sum;i>=0;i--)
{
if(dp[n][i]!=-1)
{
printf("%I64d\n",i);
return 0;
}
}
return 0;
}