大概写了一个小程序去决定今天要做什么。
每天可以叉掉一个任务。
然后随机生成另外的一个任务。
#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
using namespace std;
string str[] =
{
"学习一章节圆锥曲线",
"学习一章节圆锥曲线",
"跑两圈",
"写完50%的英语作业(有大作文的时候除外)",
"写理化作业",
"英语听力练习30min",
"背一自然段(100字)古文",
"一模题目*1",
"背上次单词",
"学习生物",
"学习物理",
"学习化学",
};
string New[] =
{
"学习一章节圆锥曲线",
"学习一章节圆锥曲线",
"跑两圈",
"写完50%的英语作业(有大作文的时候除外)",
"写理化作业",
"英语听力练习30min",
"背一自然段(100字)古文",
"一模题目*1",
"背上次单词",
"学习生物",
"学习物理",
"学习化学",
"刚刚的任务回归,并随机加入一个任务"
};
string Random_Type[] =
{
"并查集",
"贪心",
"dp",
"dp",
"高级数据结构1道",
"前缀和",
"MST",
"线性代数",
"数论",
"数论",
"数论",
"图论",
"莫队 || 分块",
"字符串",
"图论"
};
string Web[] =
{
"http://blog.csdn.net/viphong/article/details/52596852"
};
#define SIZE 1
int main()
{
int n;
scanf("%d",&n);
srand(n);
int a = rand() % 15;
cout << Random_Type[a] << endl;
for(int i = 0;i < SIZE;++ i)cout << Web[i] << endl;
int b = rand() % 12,c;
while((c = rand() % 12) == b)c = rand() % 12;
cout << str[b] << endl;
cout << str[c] << endl;
puts("Delete?");
char s[10];
scanf("%s",s + 1);
if(s[1] == 'N')return 0;
else
{
int d = rand() % 13;
while(d == b || d == c)d = rand() % 13;
cout << New[d] << endl;
puts("Happy Or Sad ?");
scanf("%s",s + 1);
int e = d;
if(s[1] == 'S')
{
while(d == b || d == c || d == e)d = rand() % 13;
cout << New[d] << endl;
}
else return 0;
}
return 0;
}
反正只是给我自己用的哈哈哈
Upd On 10.8
1.HDU 5900(DP)
Upd On 10.9
1.HDU 5800 To My Girlfriend
相当于询问存在恰好两个选两个不选的子集和大小<=m的方案数。
f[i][j][2][2]转移一下就没了。
2.HDU 5794 A Simple Chess
Lucas定理的题目,感觉很有趣啊。
可惜没A
3.Codeforces Round #301 (Div. 2) D
暴力dp.
Upd On 10.11
1.ZJOI 2013 蚂蚁寻路
考虑到确定一个矩形只需要知道它的右下角的顶点坐标以及长和宽(废话),而第i行的数组可以滚动数组更新第(i+1)行。
那么我们令
f([i])[j][k][h]
为右下角为(i,j)的第k个子矩形且高度为h的最优和。
我们显然此时的转移代价很大,考虑优化:
记录
g([i])[j][k][h][0/1]
为右下角为(i,j)的第k个子矩形且高度小于/大于h的最优和。
那么:
f([i])[j][k][h]=max(f[i][j−1][k][h],g[i][j−1][k][h][kmod2])+s[i][j]−s[h−1][j]
因为数组是滚动更新的,所以每次移动一次i的时候相当于加上了第h行到第i行的这些数字。维护下列的前缀和就可以
O(1)
转移了。
#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
using namespace std;
typedef long long LL;
const int N = 103;
const int inf = (1 << 30) - 5;
int K,n,m,ans;
int f[N][N][25],g[N][N][25][2],s[N][N];
int main()
{
ans = - inf;
scanf("%d%d%d",&n,&m,&K);
K <<= 1,K |= 1;
Rep(i,n){Rep(j,m)scanf("%d",&s[i][j]),s[i][j] += s[i - 1][j];}
Rep(i,K)Rep(j,n)f[0][j][i] = g[0][j][i][0] = g[0][j][i][1] = -inf;
Rep(i,n)
{
Rep(j,m)
{
Rep(k,K)
{
for(int h = i;h;-- h)
f[j][h][k] = max(f[j - 1][h][k],g[j - 1][h][k - 1][k & 1]) + s[i][j] - s[h - 1][j];
g[j][1][k][0] = -inf;
for(int h = 2;h <= i;++ h)
g[j][h][k][0] = max(g[j][h - 1][k][0],f[j][h - 1][k]);
g[j][i][k][1] = -inf;
for(int h = i - 1;h;-- h)
g[j][h][k][1] = max(g[j][h + 1][k][1],f[j][h + 1][k]);
}
ans = max(max(f[j][i][K],g[j][i][K][0]),ans);
}
}
printf("%d\n",ans);
return 0;
}
2.ZJOI 序列
忘记题号系列。。。
fi] = i & 1 ? f[i / 2] + f[i / 2 + 1] : f[i / 2];
这个嘛。
你首先考虑这个东西其实是可以记忆化搜索的……
当时太虚了不敢写map……
但是事实证明万进制+map快的不行……
代码肯定写了,不要质疑我的完成度2333
3.~~小强与阿米巴~~ZJOI 2012灾难
原本自己是比较会这道题的啊!!
感觉自己好像很厉害的样子2333
首先我们发现,如果一个节点的后继都挂掉了,那么这个节点就只能挂掉了。
那么我们考虑建立这样一棵树:
这个树上的每个节点,它灭绝之后它的子节点都会灭绝。
显然的一点是,我们可以根据拓扑序来建立这棵树。
实际上,考虑到这棵树的性质,我们发现,当某个节点的任意一个祖先灭绝了的话,就会灭绝。
考虑到题意上的东西。
一个小动物会灭绝,当且仅当它的所有食物灭绝。
这样的话,我们在这个树上就是它们的LCA。
那么,这个节点就是LCA的儿子节点辣。
我们怎么找LCA呢?
显然的一点是,可以动态倍增维护LCA。
这样的话我们的复杂度就是正常的辣!
#include<bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
#define v edge[i].to
#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)
using namespace std;
const int N = 70001;
int m,n,dep[N],head[N],cnt,fa[N][20],in[N];
struct Edge{int next,to;}edge[N << 1];
void save(int a,int b){edge[cnt] = (Edge){head[a], b},head[a] = cnt ++;}
queue<int>q;
namespace Graph
{
int head[N],cnt,cur[N];
struct Edge{int next,to;}edge[N << 1];
void save(int a,int b){edge[cnt] = (Edge){head[a], b},head[a] = cnt ++;}
void dfs(int x)
{
cur[x] = 1;
RepG(i,x)
{
dfs(v);
cur[x] += cur[v];
}
}
}
int LCA(int x,int y)
{
if(dep[x] < dep[y])swap(x,y);
for(int i = 19;~ i;-- i)
if(dep[fa[x][i]] >= dep[y])
x = fa[x][i];
if(x == y)return x;
for(int i = 19;~ i;-- i)
if(fa[x][i] != fa[y][i])
x = fa[x][i],y = fa[y][i];
return fa[x][0];
}
vector<int>vec[N];
int main ()
{
memset(Graph::head,-1,sizeof(Graph::head));
memset(head,-1,sizeof(head));
cnt = Graph::cnt = 0;
scanf("%d",&n);
Rep(i,n)
{
int x;
while(scanf("%d",&x),x)save(x,i),in[i] ++,vec[i].push_back(x);
}
Rep(i,n)if(!in[i])in[i] = 1,save(0,i),vec[i].push_back(0);
q.push(0);
dep[0] = 1;
while(!q.empty())
{
int x = q.front();
q.pop();
if(x)
{
int lca = (*vec[x].begin());
for(vector<int> :: iterator it = vec[x].begin();it != vec[x].end();++ it)lca = LCA(lca,*it);
dep[x] = dep[lca] + 1;
fa[x][0] = lca;
for(int i = 1;i <= 19;++ i)
fa[x][i] = fa[fa[x][i - 1]][i - 1];
Graph :: save(lca,x);
}
RepG(i,x)if((-- in[v]) == 0)q.push(v);
}
Graph :: dfs(0);
Rep(i,n)printf("%d\n",Graph :: cur[i] - 1);
return 0;
}