zoukankan      html  css  js  c++  java
  • 摸鱼(一)(状压dp)

    /*
    摸鱼
     
    题意:
    有一条路上有n个坑,每个坑里面有v[i]个鱼(1<=v[i]<=100),peter从这条路走过,每个坑只能摸一次,
    peter可以选择摸或者不摸,每摸一个坑都可以得到一个摸鱼快感,摸鱼快感的大小等于
    坑中鱼的数量,但是如果该坑的两侧都没有被摸的话,就可以得到这个坑的摸鱼快感的2倍, 
    现在给你坑的数量和每个坑中鱼的数量,让你求最大的摸鱼快感
    (坑的数量小于等于1e6); 
    时间 1s; 

    */

    思路:

    (1),我的状压dp这样表示

       用dp[i][j]表示从前面位置到当前位置的能最大值(不记录后一个为的值,但是标记,后一个位置是否选择)(在考虑状态的情况下),我的每个i位置表示,其前面,后面以及本身位置的选择,

        (000) (这三个位置都没有选择)dp[i][j] = vmax[i-2];

        (001) (只选择前一个位置) dp[i][j] = (dp[i-1][2]) > (dp[i-1][3]) ? (dp[i-1][2]) : (dp[i-1][3]);

        (010) (只选择当前位置)dp[i][j] = (dp[i-1][4] + 2 * v[i]) > (dp[i-1][4] + 2 * v[i]) ? (dp[i-1][5] + 2 * v[i]) : (dp[i-1][5] + 2 * v[i]);

        (011) (不选择后一个位置)(dp[i-1][6] + v[i]) > (dp[i-1][7] + v[i]) ? (dp[i-1][6] + v[i]) : (dp[i-1][7] + v[i]);

         (100)(只选择后一个位置)dp[i][j] = 0;

         (101)(不选择当前位置)dp[i][j] = (dp[i-1][2]) > (dp[i-1][3]) ? (dp[i-1][2]) : (dp[i-1][3]);

         (110)(不选择前一个位置)(dp[i-1][4]) > (dp[i-1][5]) ? (dp[i-1][4]) : (dp[i-1][5]);

         (111)(都选择)dp[i][j] = (dp[i-1][6]) > (dp[i-1][7]) ? (dp[i-1][6]) : (dp[i-1][7]);

    最后考虑一下边界就行了。

    由于不是oj上的题,自己就打了一个代码,望大家检查错误。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long llu;
    
    const int maxn = 1e6+5;
    const ll inf = 0x3f3f3f3f3f3f;
    
    ll v[maxn],dp[maxn][8],vmax[maxn];
    
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	for (int i = 0;i<t;i++){
    		scanf ("%lld",&v[i]);
    	}
    	v[t] = 0;
    	ll maxx = -inf;
    	for (int i = 0;i<8;i++){
    		if(i == 0) dp[1][i] = 0;
    		if(i == 1) dp[1][i] = 2*v[0];
    		if(i == 2) dp[1][i] = 2*v[1];
    		if(i == 3) dp[1][i] = v[0] + v[1];
    		if(i == 4) dp[1][i] = 0;
    		if(i == 5) dp[1][i] = 2 * v[0];
    		if(i == 6) dp[1][i] = v[1];
    		if(i == 7) dp[1][i] = v[0] + v[1];
    		maxx = max(maxx,dp[1][i]);
    		vmax[1] = maxx;
    	}
    	vmax[0] = v[0]*v[0];
    	for (int i = 2;i<=t;i++){
    		maxx = -inf;
    		for (int j = 0;j<8;j++){
    			if(j == 0) dp[i][j] = vmax[i-2];
    			if(j == 1) dp[i][j] = (dp[i-1][2]) > (dp[i-1][3]) ? (dp[i-1][2]) : (dp[i-1][3]);
    			if(j == 2) dp[i][j] = (dp[i-1][4] + 2 * v[i]) > (dp[i-1][4] + 2 * v[i]) ? (dp[i-1][5] + 2 * v[i]) : (dp[i-1][5] + 2 * v[i]);
    			if(j == 3) dp[i][j] = (dp[i-1][6] + v[i]) > (dp[i-1][7] + v[i]) ? (dp[i-1][6] + v[i]) : (dp[i-1][7] + v[i]);
    			if(j == 4) dp[i][j] = 0;
    			if(j == 5) dp[i][j] = (dp[i-1][2]) > (dp[i-1][3]) ? (dp[i-1][2]) : (dp[i-1][3]);
    			if(j == 6) dp[i][j] = (dp[i-1][4]) > (dp[i-1][5]) ? (dp[i-1][4]) : (dp[i-1][5]);
    			if(j == 7) dp[i][j] = (dp[i-1][6]) > (dp[i-1][7]) ? (dp[i-1][6]) : (dp[i-1][7]);
    			maxx = maxx > dp[i][j] ? maxx : dp[i][j];
    		}
    		vmax[i] = maxx;
    	}
    	printf("%lld
    ",vmax[t]);
    	return 0;
    }
  • 相关阅读:
    Fragments (Android官方文档中文版)
    android文件存储的4种方式
    【翻译】C# 使用Image Guid 验证图片类型
    【转载】C# 在线程同步中使用信号量
    【翻译】SQL SERVER 2008 发送DataBase Mail
    【原创】C# Linq to XML
    【转】Web Service身份验证
    【原创】C# HttpWebRequest 发送SOAP XML
    【原创】包含CDATA C#操作XML(无命名空间),添加/删除/编辑节点
    MSSqlServer函数Len()、DataLength()
  • 原文地址:https://www.cnblogs.com/Nlifea/p/11745995.html
Copyright © 2011-2022 走看看