国庆 day 7 上午

 

 思路:模拟,set记录一下。

#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
set<int>se;
int n,k,x,ans;
int main(){
    freopen("del.in","r",stdin);
    freopen("del.out","w",stdout);
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        if(se.find(x)!=se.end())    k--;
        else{
            se.insert(x);
            ans++;
        }
    }
    if(k<=0)    cout<<ans<<endl;
    else cout<<ans-k<<endl;
}
View Code

 

 

 思路:搜索

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;

int board[10][10], isKing[10][10];
int dir[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
int best_deep;
vector<int> w;
vector<int> ways;

void dfs(int step, int x, int y, int isKing)
{
    w.push_back(x * 10 + y);
    if (step > best_deep)
    {
        best_deep = step;
        ways.clear();
        ways.push_back(w[0]);
    }
    else if (step > 1 && step == best_deep)
    {
        ways.push_back(w[0]);
    }

    int dis_limit = isKing ? 9 : 2;

    for (int d = 0; d < 4; d++)
    {
        bool pass = false;
        int passx = 0, passy = 0;
        for (int dis = 1; dis <= dis_limit; dis++)
        {
            int nxtX = x + dis * dir[d][0];
            int nxtY = y + dis * dir[d][1];
            if (!(0 <= nxtX && nxtX < 10 && 0 <= nxtY && nxtY < 10))
                break;
            if (board[nxtX][nxtY] == 1 || board[nxtX][nxtY] == 3)
                break;
            if (pass && board[nxtX][nxtY] == 2)
                break;
            if (board[nxtX][nxtY] == 2)
            {
                pass = true;
                passx = nxtX;
                passy = nxtY;
            }
            else
            {
                if (!pass)
                    continue;
                board[passx][passy] = 3;
                dfs(step + 1, nxtX, nxtY, isKing);
                board[passx][passy] = 2;
            }
        }
    }
    w.pop_back();
}

bool getAvailable()
{
    ways.clear();
    w.clear();
    best_deep = 1;
    for (int curX = 0; curX < 10; curX++)
        for (int curY = 0; curY < 10; curY++)
            if (board[curX][curY] == 1)
                dfs(1, curX, curY, isKing[curX][curY]);
    if (best_deep == 1)
    {
        for (int curX = 0; curX < 10; curX++)
            for (int curY = 0; curY < 10; curY++)
                if (board[curX][curY] == 1)
                {
                    if (isKing[curX][curY])
                    {
                        for (int x = curX + 1, y = curY + 1; 0 <= x && x < 10 && 0 <= y && y < 10; x++, y++)
                            if (!board[x][y])
                                ways.push_back(curX * 10 + curY);
                            else
                                break;
                        for (int x = curX + 1, y = curY - 1; 0 <= x && x < 10 && 0 <= y && y < 10; x++, y--)
                            if (!board[x][y])
                                ways.push_back(curX * 10 + curY);
                            else
                                break;
                        for (int x = curX - 1, y = curY + 1; 0 <= x && x < 10 && 0 <= y && y < 10; x--, y++)
                            if (!board[x][y])
                                ways.push_back(curX * 10 + curY);
                            else
                                break;
                        for (int x = curX - 1, y = curY - 1; 0 <= x && x < 10 && 0 <= y && y < 10; x--, y--)
                            if (!board[x][y])
                                ways.push_back(curX * 10 + curY);
                            else
                                break;
                    }
                    else
                    {
                        if (curX - 1 >= 0 && curY - 1 >= 0 && !board[curX - 1][curY - 1])
                            ways.push_back(curX * 10 + curY);
                        if (curX - 1 >= 0 && curY + 1 < 10 && !board[curX - 1][curY + 1])
                            ways.push_back(curX * 10 + curY);
                    }
                }
    }
    if (!ways.size())
        return false;
    return true;
}

int main(){
    freopen("chess.in", "r", stdin);
    freopen("chess.out", "w", stdout);
    memset(board, 0, sizeof(board));
    memset(isKing, 0, sizeof(isKing));
    for (int i = 0; i < 10; i++)
        for (int j = 0; j < 10; j++)
        {
            char c;
            scanf(" %c", &c);
            board[i][j] = c - '0';
        }
    for (int i = 0; i < 10; i++)
        for (int j = 0; j < 10; j++)
        {
            char c;
            scanf(" %c", &c);
            isKing[i][j] = c - '0';
        }
    getAvailable();
    if (!ways.size())
        printf("0\n");
    else {
        sort(ways.begin(), ways.end());
        printf("%d\n", (int)ways.size());
        for (int i = 0; i < (int)ways.size(); i++)
            printf("(%d,%d)\n", ways[i] / 10 + 1, ways[i] % 10 + 1);
    }    
}
View Code

 

 思路:状压DP.

对后续决策有影响的是什么?

现在已经吃了哪些馅饼

令F[i][s]表示考虑前i次馅饼掉落事件,吃了s这个二进制状态表示的馅饼,期望的美味值

对于每一次掉馅饼,枚举掉下来的馅饼是谁

若s&a[j]==a[j](a[j]为前提馅饼集合) F[i][s] -> F[i+1][s|(1<<(j-1))] 注意要 /n

递推的顺序?

一个起始状态,多个目标状态,正推会导致无效状态

反着推

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,k,x,y; 
int w[20],f[20];
double dp[110][40010];
int main(){
    freopen("bonus.in","r",stdin);
    freopen("bonus.out","w",stdout);
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++){
        scanf("%d",&w[i]);
        while(scanf("%d",&x)&&x) f[i]|=1<<x-1;
    }
    for(int s=0;s<(1<<n);s++) dp[k][s]=0;
    for(int i=k-1;i>=0;i--)
        for(int s=0;s<(1<<n);s++)
            for(int j=0;j<n;j++)
                if((s&f[j])==f[j]) dp[i][s]+=1.0/n*max(dp[i+1][s],dp[i+1][s|(1<<j)]+w[j]);
                else dp[i][s]+=1.0/n*dp[i+1][s];
    printf("%.6f\n",dp[0][0]);
}
View Code

 

转载于:https://www.cnblogs.com/cangT-Tlan/p/7642885.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值