随机规划自己的一天系列233

大概写了一个小程序去决定今天要做什么。
每天可以叉掉一个任务。
然后随机生成另外的一个任务。

#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][j1][k][h],g[i][j1][k][h][kmod2])+s[i][j]s[h1][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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值