个人感觉是最短路大冒险……
(不知道为啥中暑了脑子反而活跃了起来,就是代码实现非常gg)
fzu 2253 Salty Fish
渔夫翻咸鱼,会把一个区间里的1翻成0 0翻成1
区间长度至少为1
问最多有几个1
统计原先的咸鱼数量
考虑每翻一次,如果本来是1 会使咸鱼数量-1,如果本来是0,会使咸鱼数量+1
所以把数组更改为-1 +1
即数组变为翻该鱼会对总鱼数的影响
然后求一个最大连续子序列和
最大值(翻身影响)+原来的鱼数=最大鱼数
但是因为至少要翻一条鱼
所以特殊情况就是明明本来都是翻身的咸鱼,还一定要-1
#include
#include
#include
#include
using namespace std;
const int maxn=100010;
#define eps 1e-8
int s[maxn],a[maxn];
int main()
{
int cases,i,j,ans,cnt,now,maxx,n;
while (~scanf("%d",&n))
{
ans=0; cnt=0; now=0;
memset(s,0,sizeof(s));
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if (a[i]) ans++;
if (i==1 || a[i]!=a[i-1]) cnt++;
if (a[i]==0) s[cnt]++; else s[cnt]-=1;
}
maxx=0;
for (i=1;i<=cnt;i++)
{
if (now+s[i]>0) now+=s[i]; else now=0;
maxx=max(maxx,now);
}
if (maxx) printf("%d\n",ans+maxx); else printf("%d\n",ans-1);
}
return 0;
}
fzu 2254 英语考试
比赛的时候……用了各种姿势
最短路 拓扑 wa的死去活来
……后来发现最短路能ac 但是我忘记初始化了……
最短路能ac,但总感觉怪怪的
每个单词一定存在的一种花费是len
或者从已经背诵的单词转移过来,需要的花费是hamming(Si, T) * w
用最短路的思路去更新,先记录各个单词之间转移需要的花费
每次找需要花费最少的单词进行背诵,然后更新未被背诵的单词
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1010;
const int INF=0x3f3f3f3f;
int len;
int n,mar[maxn][maxn],fin[maxn],dis[maxn];
int ind[maxn],vis[maxn];
vector<int>G[maxn];
void Dijkstr(int source)
{
memset(fin,0,sizeof(fin));
int i,j,minx,nextp;
for (i=1;i<=n;i++)
{
fin[i]=0;
dis[i]=mar[source][i];
}
fin[source]=1;
dis[source]=0;
for (i=2;i<=n;i++)
{
minx=INF;
for (j=1;j<=n;j++)
if (fin[j]==0 && dis[j]if (minx==INF) return;
fin[nextp]=1;
for (j=1;j<=n;j++)
if (fin[j]==0 && mar[nextp][j]char ss[maxn][15];
int main()
{
int cases,m,u,v,w,sum,minn,mini;
while (~scanf("%d%d%d",&n,&len,&w))
{
for (int i=1;i<=n;i++)
{
scanf("%s",ss[i]);
G[i].clear();
dis[i]=len;
}
memset(mar,0,sizeof(mar));
minn=len; mini=1;
for (int i=1;ifor (int j=i+1;j<=n;j++)
{
mar[i][j]=len; sum=0;
for (int k=0;kif (ss[i][k]!=ss[j][k]) sum+=w;
if (sumif (mar[i][j]for (int i=1;i<=n;i++) sum+=dis[i];
printf("%d\n",sum);
}
return 0;
}
过河
fzu 2256 迷宫
一棵树
n个点
接下来n-1行,第i行包含两个数字Pi和Wi,表示i+1号房间的上级房间为Pi,道路长度为Wi。
子节点和父节点之间的路是wi
也就是说任意两点光靠走路其实都是相通的
每个房间拥有一个时空传送门,第i个房间的传送门可以花费Di单位的时间传送到它的任意一个下级房间中(如果x是y的下级房间,并且y是z的下级房间,那么x也是z的下级房间)
这里意味着父节点都有传送阵,可以传送到任意子节点。
所以考虑把利用dfs把子节点都传递上来,建边,花费d[i]
跑个最短路……输出
比赛的时候疯狂mle是因为模板里有个判断负环的数组没删QAQ(这样也行嘛)
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=100010;
const int INF=0x3f3f3f3f;
int dis[maxn],inq[maxn];
int n,d[maxn];
struct points
{
int v,w;
};
vector G[maxn];
vector<int>son[maxn];
void add_edge(int u,int v,int w)
{
points now;
now.v=v;
now.w=w;
G[u].push_back(now);
}
void SPFA(int source)
{
int u,v,w,i;
memset(inq,0,sizeof(inq));
for (i=0;i<=n+1;i++) dis[i]=INF;
dis[source]=0;
inq[source]=1;
queue<int>q;
points now;
q.push(source);
while (!q.empty())
{
u=q.front(); q.pop();
inq[u]=0;
for (i=0;iif (dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if (!inq[v])
{
inq[v]=1;
q.push(v);
}
}
}
}
return;
}
void dfs(int now)
{
int v,vv;
for (int i=0;iint xx=son[now].size();
for (int i=0;ifor (int j=0;jreturn;
}
int main()
{
int cases,m,u,v,w,S;
while (~scanf("%d",&n))
{
for (int i=1;i<=n;i++) { scanf("%d",&d[i]); G[i].clear(); son[i].clear();}
for (int i=2;i<=n;i++)
{
scanf("%d%d",&u,&w);
son[u].push_back(i);
if (welse add_edge(u,i,d[u]);
}
dfs(1);
SPFA(1);
for (int i=1;i<=n;i++) printf("%d ",dis[i]);
printf("\n");
}
return 0;
}
Saya的小熊饼干
dalao说是原题。。。http://acm.hdu.edu.cn/showproblem.php?pid=5245
fzu 2258 奖励
不能用除法……判断总分>=240且单科都>=60就好了。
图
Card Game
浪里个浪
多起点多终点最短路
把所有可能的起点和零点建边,路程为0
把所有可能的终点和n+1点建边,路程为0
跑一遍从0点开始的最短路,输出到n+1这个点的最短路程
和hdu 2066类似
不过因为hdu那题数据小,……我跑了s遍最短路……emmmmm