T1音量调节
一看这数据范围,不就dfs么。
#include <bits/stdc++.h>
using namespace std;
int a[6666],n,beg,maxx,ans=-1;
bool flag[601][1110];
void dfs(int x,int y)//x记录音量,y记录唱到第几首
{
if(flag[y][x]==1)//如果该状态出现过,就return
{
return ;
}
flag[y][x]=1;//记录这个状态
if(x>maxx)//音量过高就return
return ;
if(x<0)//音量过低就return
return ;
if(y>n)//如果活着唱完
{
ans=max(ans,x);//记录是不是最高音
return ;
}
dfs(x+a[y],y+1);//音量增加a[y]
dfs(x-a[y],y+1);//减少
return ;
}
int main()
{
cin>>n>>beg>>maxx;//输入唱几首歌开始音量和最高音量
for(int i=1;i<=n;i++)
cin>>a[i];
dfs(beg,1);//初始音量和第一首歌
cout<<ans;
return 0;
}
勉强算个记忆化搜索吧,一开始没定义flag,后来发现可以依据DP应有的“不重不漏”,记录每次唱到第几首的时候音量多少,极大避免重复现象,而dfs本身就不容易漏。
交的时候没注意把
if(flag[y][x]==1)//如果该状态出现过,就return
{
return ;
}
flag[y][x]=1;//记录这个状态
写成了
if(flag[x][y]==1)//如果该状态出现过,就return
{
return ;
}
flag[x][y]=1;//记录这个状态
导致数组越界,只有10分。
该出来后只有50分,看了看错误又看了看题,发现是题看错了
看成了过程中的最大音量,就离谱,这还50分
改完之后成了现在这副模样,终于愉快地AC了。
更离谱的是在洛谷中可以看到
河南省选难度普及-
T2
看了之后发现是状压DP,但第一时间没思路直接跳了
T3 补兵
题目大意
在玩刀塔的时候队友老鹿抢你兵线,你玩幽鬼,你先攻击,每次能打一个小兵一滴血,而老鹿让所有小兵减少一滴血,问你能补到多少兵。
我玩游戏的时候还补不到兵呢写个这就能补到了???
还是没有正解思路,于是想打个暴力,记录血量为i的小兵个数,如果个数大于2且i大于3,则打一下这个小兵,让小兵的血量尽可能错开,不过首先要把血量为1的小兵先打掉。
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int zuida,t,b[N],a,n,ans;
void init()//输入数据
{
ans=0;
memset(b,0,sizeof b);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a;
b[a]++;
zuida=max(zuida,a);
}
}
void work(int x)//看补兵,x记录血量最多的兵的血量
{
if(x<=0)//都死了
{
return ;
}
if(b[1])//如果有小兵血量为1
{
ans++;//为答案贡献1
for(int i=1;i<=x;i++)//老鹿AOE小兵每个减少1滴血
{
b[i]=b[i+1];
}
x--;//最大的血量比原来少1
work(x);
return ;
}
for(int i=3;i<=x;i++)//想办法让小兵血量错开
{
if(b[i]>1)
{
b[i]--;
b[i-1]++;
}
}
for(int i=1;i<=x;i++)
{
b[i]=b[i+1];
}
x--;
work(x);
return ;
}
int main()
{
cin>>t;
while(t--)
{
init();
work(zuida);
cout<<ans<<endl;
}
return 0;
}
写的时候感觉做过一道类似的题但死活想不出来,最后骗了10分,这个比赛里算是没有更高的了……
正解思路
T4 CF111C Petya and Spiders
又双叒叕是状压DP,但是在老师给的PDF中可见
只水个50%的分我觉得就很棒
于是在纸上写写画画,感觉三个连一起,左右两个都移动到中间格子的话收益最大。
#include <bits/stdc++.h>
using namespace std;
int a,b,m,n,ans;
void work1()
{
a=m/3;
b=m%3;
if(b==0)
{
ans+=2*a;
}
if(b==1)
{
ans+=2*a;
}
if(b==2)
{
ans+=a*2;
ans+=1;
}
}
void work2()
{
a=m/3;
b=m%3;
if(b==0)
{
ans+=(m/3)*2*n;
}
if(b==1)
{
ans+=(m/3)*2*n;
ans+=1;
}
if(b==2)
{
ans+=a*2*n;
ans+=2;
}
}
void workn3()
{
a=n/3;
ans+=m*2*a;
}
void workm3()
{
a=m/3;
ans+=2*n*a;
}
void work()
{
a=n/3;
b=n%3;
ans+=m*2*a;
m=b;
if(n==1) work1();
else if(n==2) work2();
}
int main()
{
cin>>n>>m;
if(m<n)
swap(m,n);
int rp;
rp++;
if(n%3==0) workn3();
else if(m%3==0) workm3();
else if(n==1) work1();
else if(n==2) work2();
else work();
cout<<ans;
return 0;
}
分段写了一下,最后感觉把大数据拆开写说不定能AC掉于是写了work(),于是高高兴兴拿了30,成绩出来后也确实没人得50,经老师提点,有一个更好的方法水,保证n是m,n中较小的数,而由m*n≤40可得,此时的n最大是6,6×6=36,数据还一定是整数,按照这个思路的话数也应该数很多分。
T5 奶牛大聚会
题目描述
Bessie 正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会。当然,她会选择最方便的地点来举办这次集会。
每个奶牛居住在 N 个农场中的一个,这些农场由N−1 条道路连接,并且从任意一个农场都能够到达另外一个农场。道路 i 连接农场 Ai 和 Bi,长度为Li。集会可以在 N 个农场中的任意一个举行。另外,每个牛棚中居住着 Ci 只奶牛。
在选择集会的地点的时候,Bessie 希望最大化方便的程度(也就是最小化不方便程度)。比如选择第 X 个农场作为集会地点,它的不方便程度是其它牛棚中每只奶牛去参加集会所走的路程之和(比如,农场 ii到达农场 X 的距离是 20,那么总路程就是 Ci×20)。帮助 Bessie 找出最方便的地点来举行大集会。
输入格式
第一行一个整数 N 。
第二到 N+1 行:第 i+1 行有一个整数 Ci。
第 N+2 行到 2N 行:第i+N+1 行为 3 个整数:Ai,Bi 和 Li。
输出格式
一行一个整数,表示最小的不方便值。
分析过程:
1.首先这是USACO 的题
2.感觉是树形DP
3.Floyd能不能水
4.快到时间了,检查下其他的有没有什么问题吧